1. 程式人生 > >【網絡流24題】分配問題

【網絡流24題】分配問題

string 方案 while 設計 ring cost -s alt 接下來

【網絡流24題】分配問題

Description

有n件工作要分配給n個人做。第i 個人做第j 件工作產生的效益為ij c 。試設計一個將n件工作分配給n個人做的分配方案,使產生的總效益最大。
對於給定的n件工作和n個人,計算最優分配方案和最差分配方案。

Input

第1 行有1 個正整數n,表示有n件工作要分配給n 個人做。
接下來的n 行中,每行有n 個整數ij c ,1≤i≤n,1≤j≤n,表示第i 個人做第j件工作產生的效益為ij c 。

Output

將計算出的最小總效益和最大總效益輸出

Sample Input

5
2 2 2 1 2
2 3 1 2 4
2 0 1 1 1
2 3 4 3 3
3 2 1 2 1

Sample Output

5
14

Hint

數據範圍:
N<=100

Source

網絡流
二分圖最佳匹配,最小費用最大流

當費用流練手題吧。。。好久沒打了。(好像不用費用流。。。)S向工作,人向T連w=1,cost=0的邊,然後工作a向人b連w=1,cost=c[i][j]的邊,跑費用流,輸出。。。所有邊權×=-1,再跑一遍。。。

技術分享
 1 // It is made by XZZ
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
 7 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
 8 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
 9 #define
il inline 10 #define rg register 11 #define vd void 12 #define t (dis[i]) 13 typedef long long ll; 14 il int gi(){ 15 rg int x=0;rg char ch=getchar(); 16 while(ch<0||ch>9)ch=getchar(); 17 while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar(); 18 return x; 19 } 20 const int maxn=101+101+10,maxm=(101*101+100)<<1,S=1,T=2; 21 int fir[maxn],dis[maxm],nxt[maxm],w[maxm],cost[maxm],id=1; 22 il vd add(int a,int b,int W,int C){ 23 nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=W,cost[id]=C; 24 if(W)add(b,a,0,-C); 25 } 26 int nw[101],np[101]; 27 il bool Super_Fast(int&Cost){ 28 int que[maxn],hd=0,tl=1,Dis[maxn],last[maxn]={0};bool inque[maxn]={0}; 29 memset(Dis,127/3,sizeof Dis);Dis[S]=0; 30 que[0]=S,inque[S]=1; 31 while(hd^tl){ 32 int now=que[hd];hd=(hd+1)%maxn,inque[now]=0; 33 erep(i,now) 34 if(Dis[now]+cost[i]<Dis[t]&&w[i]){ 35 Dis[t]=Dis[now]+cost[i],last[t]=i; 36 if(!inque[t])que[tl++]=t,inque[t]=1,tl%=maxn; 37 } 38 } 39 if(!last[T])return false; 40 rg int flow=666666666; 41 for(rg int i=last[T];i;i=last[dis[i^1]])flow=min(flow,w[i]); 42 for(rg int i=last[T];i;i=last[dis[i^1]])w[i]-=flow,w[i^1]+=flow,Cost+=cost[i]*flow; 43 return true; 44 } 45 il int mincost(int Cost=0){ 46 while(Super_Fast(Cost)); 47 return Cost; 48 } 49 int main(){ 50 int n=gi(); 51 rep(i,1,n)nw[i]=i+2,add(S,nw[i],1,0); 52 rep(i,1,n)np[i]=i+n+2,add(np[i],T,1,0); 53 rep(i,1,n)rep(j,1,n)add(nw[i],np[j],1,gi()); 54 printf("%d\n",mincost()); 55 rep(i,2,id)w[i]=1-(i&1),cost[i]*=-1; 56 printf("%d\n",-mincost()); 57 return 0; 58 }
View Code

【網絡流24題】分配問題