首页 > 代码库 > 【网络流24题】分配问题

【网络流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


正解:最小费用最大流,最大费用最大流

解题报告:裸的网络流。。。

 1 #include <iostream>
 2 #include <iomanip>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <string>
 8 #include <algorithm>
 9 #define RG register
10 #define MIN(a,b) a<b?a:b
11 const int N = 100000;
12 const int M = 1000000;
13 const int inf = 2147483641;
14 
15 using namespace std;
16 
17 int head[N],a[105][105],nxt[N],f[M],vis[N];
18 int cnt=1,S,T,ans,dis[N],fa[N];
19 
20 int gi(){
21     char ch=getchar();int x=0;
22     while(ch<0 || ch>9) ch=getchar();
23     while(ch>=0 && ch<=9) x=x*10+ch-0,ch=getchar();
24     return x;
25 }
26 
27 struct date{
28     int from,to,val,s;
29 }nn[N];
30 
31 void link(int l,int r,int val,int s){
32     nn[++cnt]=(date){l,r,val,s},nxt[cnt]=head[l],head[l]=cnt;
33     nn[++cnt]=(date){r,l,0,-s},nxt[cnt]=head[r],head[r]=cnt;
34     return;
35 }
36 
37 int spfa(){
38     for (RG int i=S; i<=T; ++i) dis[i]=inf;
39     int l=0,r=1;
40     f[1]=0,dis[0]=0,vis[0]=1;
41     while(l<r){
42         ++l;
43         for (RG int i=head[f[l]]; i; i=nxt[i])
44             if (nn[i].val && dis[f[l]]+nn[i].s<dis[nn[i].to]){
45                 dis[nn[i].to]=dis[f[l]]+nn[i].s;
46                 fa[nn[i].to]=i;
47                 if (vis[nn[i].to]==0)
48                     f[++r]=nn[i].to,vis[nn[i].to]=1;
49             }
50         vis[f[l]]=0;
51     }
52     if (dis[T]==inf) return 0;
53     int gg=inf;
54     for (RG int i=fa[T]; i; i=fa[nn[i].from]) gg=MIN(gg,nn[i].val);
55     for (RG int i=fa[T]; i; i=fa[nn[i].from]) nn[i].val-=gg,nn[i^1].val+=gg;
56     ans+=dis[T]*gg;
57     return 1;
58 }
59 
60 int main(){
61     int n=gi();T=2*n+1;
62     for (RG int i=1; i<=n; ++i){
63         link(S,i,1,0);
64         link(i+n,T,1,0);
65         for (RG int j=1; j<=n; ++j){
66             a[i][j]=gi();
67             link(i,j+n,1,a[i][j]);
68         }
69     }
70     while(spfa());
71     printf("%d\n",ans);ans=0,cnt=1;
72     for (RG int i=S; i<=T; i++) head[i]=0;
73     for (RG int i=1; i<=n; ++i){
74         link(S,i,1,0);
75         link(i+n,T,1,0);
76         for (RG int j=1; j<=n; ++j)
77             link(i,j+n,1,-a[i][j]);
78     }
79     while(spfa());
80     printf("%d\n",-ans);
81     return 0;
82 }

 

【网络流24题】分配问题