Luo Gu P4014: "distribution"
Title Description
N has the job to be assigned to individual n do. Do person i benefits generated by the operation member as a j C i j . N will try to design a piece of work is assigned to n do individual allocation, the maximum total benefits derived .
Input Format
Line 1 has a document positive integer n, the n-n to be assigned to the job done individuals. The following n rows, each row having n integers C i j , i denotes the j-th individual members do benefits arising from the work for the C i J .
Output Format
Two lines are the smallest total output efficiency and maximum total benefit.
Sample input and 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
Description / Tips
. 1 ≤ n- ≤ . 1 0 0 a repair man only one workpiece
This is a cost flow Classic title
Construction Plan
- 1. 0 super set point source, 2 × n-+ super sink. 1, the i-th individual nodes i, j-th node of the job j + n
- 2. From the source point to the super ∀ I ∈ [1, n-] connected to a capacity of 1, 0 edge cost
- 3. ∀ J ∈ [n-+ 1,2 × n-] connected to a meeting point to the ultra-capacity is 1, the cost is 0 side
- 4. From ∀i ∈ [1, n-] to ∀j ∈ [+ n-1, n- × 2], a capacity of a connection fee of C I , J side
practice
Run over a minimum cost maximum flow & minimum cost maximum flow, and then output the minimum and maximum values (Reminder:! Be sure to output, or will WA)
I presented ugly codes for you big brother ~
1 #include<bits/stdc++.h> 2 #define FQ(i,a,b) for(register int i=a;i<=b;i++) 3 #define prf printf 4 #define scf scanf 5 #define ll long long 6 using namespace std; 7 const int N=5e4+10; 8 int INF,n,num=1,ne[N],fi[N],to[N],w[N],pl[N],S,T; 9 int dst[N],incf[N],P[N],vis[N],ans; 10 queue<int> q; 11 void FindMaxN() 12 { 13 int fINDmAXn[1]; 14 memset(fINDmAXn,128/2,sizeof(fINDmAXn)); 15 INF=fINDmAXn[0]; 16 } 17 ll read() 18 { 19 ll x=0,f=1;char ch=getchar(); 20 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 21 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 22 return x*f; 23 } 24 void add(int x,int y,int z,int kl) 25 { 26 ne[++num]=fi[x]; 27 fi[x]=num; 28 to[num]=y; 29 w[num]=z; 30 pl[num]=kl; 31 } 32 bool spfa() 33 { 34 for(int i=S;i<=T;i++)dst[i]=INF; 35 memset(vis,0,sizeof(vis)); 36 q.push(S),dst[S]=0; 37 incf[S]=1<<30,vis[S]=true; 38 while(!q.empty()) 39 { 40 int x=q.front(); 41 vis[x]=false;q.pop(); 42 for(int i=fi[x];i;i=ne[i]) 43 { 44 int ver=to[i]; 45 if(dst[ver]>dst[x]+pl[i]&&w[i]) 46 { 47 dst[ver]=dst[x]+pl[i]; 48 incf[ver]=min(incf[x],w[i]); 49 P[ver]=i; 50 if(!vis[ver])vis[ver]=true,q.push(ver); 51 } 52 } 53 } 54 return dst[T]!=INF; 55 } 56 void update() 57 { 58 int x=T; 59 while(x!=S) 60 { 61 int i=P[x]; 62 w[i]-=incf[T]; 63 w[i^1]+=incf[T]; 64 65 x=to[i^1]; 66 } 67 ans+=dst[T]*incf[T]; 68 } 69 bool spfa_d() 70 { 71 for(int i=S;i<=T;i++)dst[i]=-INF; 72 q.push(S),dst[S]=0;incf[S]=1<<30; 73 while(!q.empty()) 74 { 75 int x=q.front(); 76 vis[x]=false;q.pop(); 77 for(int i=fi[x];i;i=ne[i]) 78 { 79 int ver=to[i]; 80 if(dst[ver]<dst[x]+pl[i]&&w[i]) 81 { 82 dst[ver]=dst[x]+pl[i]; 83 incf[ver]=min(incf[x],w[i]); 84 P[ver]=i; 85 if(!vis[ver])vis[ver]=true,q.push(ver); 86 } 87 } 88 } 89 return dst[T]!=-INF; 90 } 91 void update_d() 92 { 93 int x=T; 94 while(x!=S) 95 { 96 int i=P[x]; 97 w[i]-=incf[T]; 98 w[i^1]+=incf[T]; 99 x=to[i^1]; 100 } 101 ans+=dst[T]*incf[T]; 102 } 103 void add_x(int x,int y,int z,int kl) 104 { 105 add(x,y,z,kl); 106 add(y,x,0,-kl); 107 } 108 int main() 109 { 110 //freopen(".in","r",stdin); 111 //freopen(".out","w",stdout); 112 FindMaxN(); 113 n=read();S=0,T=n*2+1; 114 for(int i=1;i<=n;i++) 115 { 116 for(int j=1;j<=n;j++) 117 { 118 int x=read(); 119 add_x(i,j+n,1,x); 120 } 121 } 122 for(int i=1;i<=n;i++)add_x(S,i,1,0),add_x(i+n,T,1,0); 123 while(spfa())update(); 124 printf("%d\n",ans); 125 ans=0; 126 for(int i=2;i<=num;i+=2)w[i]+=w[i^1],w[i^1]=0; 127 while(spfa_d())update_d(); 128 printf("%d\n",ans); 129 return 0; 130 } 131 //**月雩·薇嫭**
by: yu-Wei Hu month