zoukankan      html  css  js  c++  java
  • 【BZOJ1449&&2895】球队预算 [费用流]

    球队预算

    Time Limit: 10 Sec  Memory Limit: 256 MB
    [Submit][Status][Discuss]

    Description

      在一个篮球联赛里,有n支球队,
      球队的支出是和他们的胜负场次有关系的,具体来说,第i支球队的赛季总支出是Ci*x^2+Di*y^2,Di<=Ci。(赢得多,给球员的奖金就多嘛)
      其中x,y分别表示这只球队本赛季的胜负场次。
      现在赛季进行到了一半,每只球队分别取得了a[i]场胜利和b[i]场失利。
      而接下来还有m场比赛要进行。
      问联盟球队的最小总支出是多少。

    Input

      第一行n,m

      接下来n行每行4个整数a[i],b[i],Ci,Di

      再接下来m行每行两个整数s,t表示第s支队伍和第t支队伍之间将有一场比赛,注意两只队间可能有多场比赛。

    Output

      输出总值的最小值。

    Sample Input

      3 3
      1 0 2 1
      1 1 10 1
      0 1 3 3
      1 2
      2 3
      3 1

    Sample Output

      43

    HINT

      2<=n<=5000,0<=m<=1000,0<=di<=ci<=10,0<=a[i],b[i]<=50.

    Solution

      这题很棒棒,肯定是个费用流。我们可以首先假设所有场次都是输的,然后每次调整赢的场次来获得最小答案。
      怎么建边呢?
        S->比赛 流量为1,费用为0 mean : 一场比赛
        比赛->两只队伍 流量为1,费用为0 mean : 流过去则表示这支队伍获得了胜利
        队伍->T 连若干条边,流量为1,费用为 C*(2a+1)-D*(2b-1) mean : 获胜得到的收益
        为什么呢?这个可以用平方关系得到(多赢一场,少输一场)
      然后用原来的答案+最小费用即可。

    Code

      1 #include<iostream>  
      2 #include<string>  
      3 #include<algorithm>  
      4 #include<cstdio>  
      5 #include<cstring>  
      6 #include<cstdlib>  
      7 #include<cmath>
      8 using namespace std;
      9 typedef long long s64;
     10  
     11 const int ONE = 50001;
     12 const int EDG = 1000001;
     13 const int INF = 2147483640;
     14  
     15 int n,m;
     16 int x,y;
     17 int S,T;
     18 int Num[ONE];
     19 int next[EDG],first[ONE],go[EDG],from[EDG],pas[EDG],w[EDG],tot;
     20 int dist[ONE],pre[ONE],vis[ONE];
     21 int tou,wei,q[ONE];
     22 int Ans;
     23 
     24 struct power
     25 {
     26         int a,b,C,D;
     27 }A[ONE];
     28 
     29 inline int get()
     30 {
     31         int res=1,Q=1;  char c;
     32         while( (c=getchar())<48 || c>57)
     33         if(c=='-')Q=-1;
     34         if(Q) res=c-48; 
     35         while((c=getchar())>=48 && c<=57) 
     36         res=res*10+c-48;
     37         return res*Q; 
     38 }
     39  
     40 void Add(int u,int v,int flow,int z)
     41 {
     42         next[++tot]=first[u];   first[u]=tot;   go[tot]=v;  from[tot]=u;    pas[tot]=flow;  w[tot]=z;
     43         next[++tot]=first[v];   first[v]=tot;   go[tot]=u;  from[tot]=v;    pas[tot]=0;     w[tot]=-z;
     44 }
     45  
     46 bool Bfs()
     47 {
     48         for(int i=S;i<=T;i++) dist[i] = INF;
     49         dist[S] = 0;    vis[S] = 1;
     50         tou = 0; wei = 1; q[1] = S;
     51         while(tou < wei)
     52         {
     53             int u = q[++tou];
     54             for(int e=first[u]; e; e=next[e])
     55             {
     56                 int v = go[e];
     57                 if(dist[v] > dist[u] + w[e] && pas[e])
     58                 {
     59                     dist[v] = dist[u] + w[e]; pre[v] = e;
     60                     if(!vis[v])
     61                     {
     62                         vis[v] = 1;
     63                         q[++wei] = v;
     64                     }
     65                 }
     66             }
     67             vis[u] = 0;
     68         }
     69         return dist[T] != INF;
     70 }
     71  
     72 void Deal()
     73 {
     74         int x = INF;
     75         for(int e=pre[T]; e; e=pre[from[e]]) x = min(x,pas[e]);
     76         for(int e=pre[T]; e; e=pre[from[e]])
     77         {
     78             pas[e] -= x;
     79             pas[((e-1)^1)+1] += x;
     80             Ans += x*w[e];
     81         }
     82 }
     83 
     84 void Build()
     85 {
     86         S=0;    T=n+m+1;
     87         for(int i=1;i<=m;i++)
     88         {
     89             x=get();    y=get();
     90             Add(S,i, 1,0);
     91             Add(i,x+m, 1,0);    Add(i,y+m, 1,0);
     92             
     93             Num[x]++;    Num[y]++; 
     94             A[x].b++;    A[y].b++;
     95         }
     96         
     97         for(int i=1;i<=n;i++)
     98         {
     99             Ans += A[i].a*A[i].a * A[i].C + A[i].b*A[i].b * A[i].D;
    100             for(int j=1;j<=Num[i];j++)
    101             {
    102                 Add(i+m,T, 1,A[i].C*(2*A[i].a+1) - A[i].D*(2*A[i].b-1) );
    103                 A[i].a++; A[i].b--;
    104             }
    105         }
    106 }
    107 
    108 int main()
    109 {
    110         n=get();    m=get();
    111         for(int i=1;i<=n;i++)
    112         {
    113             A[i].a=get();    A[i].b=get();
    114             A[i].C=get();    A[i].D=get();
    115         }
    116         
    117         Build();
    118         
    119         while(Bfs()) Deal();
    120         
    121         printf("%d",Ans);
    122         
    123 }
    View Code
  • 相关阅读:
    k8s资源编排
    虫师『软件测试』基础 与 测试杂谈
    虫师『性能测试』文章大汇总
    OMCS ——卓尔不群的网络语音视频聊天框架(跨平台)
    ESFramework ——成熟的C#网络通信框架(跨平台)
    2022.2 区块链的技术架构
    pytest文档80 内置 fixtures 之 cache 写入中文显示\u4e2d\u6587问题(用打补丁方式解决) 上海
    翻译校正
    Inside WCF Runtime
    Web Services Security
  • 原文地址:https://www.cnblogs.com/BearChild/p/6802214.html
Copyright © 2011-2022 走看看