BZOJ1449&&2895球队预算 [费用流]

Posted BearChild

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.

Source

  这题很棒棒,肯定是个费用流。我们可以首先假设所有场次都是输的,然后每次调整赢的场次来获得最小答案。
  怎么建边呢?
    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

 

以上是关于BZOJ1449&&2895球队预算 [费用流]的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1449/bzoj2895[JSOI2009]球队收益/球队预算 费用流

BZOJ1449/2895[JSOI2009]球队收益/球队预算 最小费用最大流

bozj 1449/2895: 球队预算 -- 费用流

BZOJ1449: [JSOI2009]球队收益

BZOJ2895: 球队预算

Bzoj1449 [JSOI2009]球队收益