网络流/费用流/二分图最小权匹配
题解:http://blog.csdn.net/huzecong/article/details/9119741
太神了!由于一赢一输不好建图,就先假设全部都输,再将赢的收益修改!就变成普通的二分图了!!
费用与流量的平方相关时拆边……这个稍微处理一下即可
1 /************************************************************** 2 Problem: 1449 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:676 ms 7 Memory:3940 kb 8 ****************************************************************/ 9 10 //BZOJ 1449 11 #include<cmath> 12 #include<vector> 13 #include<cstdio> 14 #include<cstring> 15 #include<cstdlib> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 #define pb push_back 22 #define CC(a,b) memset(a,b,sizeof(a)) 23 using namespace std; 24 int getint(){ 25 int v=0,sign=1; char ch=getchar(); 26 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 27 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 28 return v*sign; 29 } 30 const int N=10000,M=100000,INF=~0u>>2; 31 typedef long long LL; 32 const double eps=1e-8; 33 /*******************template********************/ 34 int n,m,w[N],l[N],c[N],d[N],du[N]; 35 LL ans; 36 struct edge{int from,to,v,c;}; 37 struct Net{ 38 edge E[M]; 39 int head[N],next[M],cnt; 40 void ins(int x,int y,int z,int c){ 41 E[++cnt]=(edge){x,y,z,c}; 42 next[cnt]=head[x]; head[x]=cnt; 43 } 44 void add(int x,int y,int z,int c){ 45 ins(x,y,z,c); ins(y,x,0,-c); 46 } 47 int S,T,d[N],from[N],Q[M]; 48 bool inq[N]; 49 bool spfa(){ 50 int l=0,r=-1; 51 F(i,0,T)d[i]=INF; 52 d[S]=0; Q[++r]=S; inq[S]=1; 53 while(l<=r){ 54 int x=Q[l++]; inq[x]=0; 55 for(int i=head[x];i;i=next[i]) 56 if(E[i].v && d[x]+E[i].c<d[E[i].to]){ 57 d[E[i].to]=d[x]+E[i].c; 58 from[E[i].to]=i; 59 if(!inq[E[i].to]){ 60 Q[++r]=E[i].to; 61 inq[E[i].to]=1; 62 } 63 } 64 } 65 return d[T]!=INF; 66 } 67 void mcf(){ 68 int x=INF; 69 for(int i=from[T];i;i=from[E[i].from]) 70 x=min(x,E[i].v); 71 for(int i=from[T];i;i=from[E[i].from]){ 72 E[i].v-=x; 73 E[i^1].v+=x; 74 } 75 ans+=x*d[T]; 76 } 77 void init(){ 78 n=getint(); m=getint(); cnt=1; ans=0; 79 S=0; T=n+m+1; 80 F(i,1,n){ 81 w[i]=getint();l[i]=getint(); 82 c[i]=getint();d[i]=getint(); 83 // ans+=w[i]*w[i]*c[i]+l[i]*l[i]*d[i]; 84 } 85 int x,y; 86 F(i,1,m){ 87 x=getint(); y=getint(); 88 du[x]++; du[y]++; 89 add(x,i+n,1,0); add(y,i+n,1,0); 90 add(i+n,T,1,0); 91 l[x]++; l[y]++; 92 } 93 F(i,1,n) ans+=w[i]*w[i]*c[i]+l[i]*l[i]*d[i]; 94 95 F(i,1,n) F(j,1,du[i]) 96 add(S,i,1,((j+w[i])*2-1)*c[i] - ((l[i]-j+1)*2-1)*d[i] ); 97 while(spfa()) mcf(); 98 printf("%lld ",ans); 99 } 100 }G1; 101 int main(){ 102 #ifndef ONLINE_JUDGE 103 freopen("input.txt","r",stdin); 104 // freopen("output.txt","w",stdout); 105 #endif 106 G1.init(); 107 return 0; 108 }
1449: [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 516 Solved: 283
[Submit][Status][Discuss]
Description
Input
Output
一个整数表示联盟里所有球队收益之和的最小值。
Sample Input
3 3
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
Sample Output
43
HINT