【网络流24题】分配问题 最小最大费用最大流
Description
有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为Cij 。试设计一个将 n件工作分配给n个人做的分配方案,使产生的总效益最大。 编程任务: 对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。
Input
由文件input.txt提供输入数据。文件的第1 行有1 个正整数n,表示有n件工作要分配 给n 个人做。接下来的n 行中,每行有n 个整数Cij ,1≤i≤n,1≤j≤n(n<=100),表示第i 个人做 第j件工作产生的效益为Cij。
Output
程序运行结束时,将计算出的最小总效益和最大总效益输出到文件output.txt中。
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
题解:
(S,人,1,0) (工作,T,1,0) (人,工作,INF,map[i][j])
然后最小费用就是跑spfa增广最小cost
最大费用就是把map[i][j]设成负的,然后一样跑spfa,答案即为-ans
可笑的是傻逼的我搞了个层次网络,然后挂了.
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int N=505,INF=1999999999; 7 int gi(){ 8 int str=0;char ch=getchar(); 9 while(ch>'9'||ch<'0')ch=getchar(); 10 while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar(); 11 return str; 12 } 13 int n,S=0,T,num=1,head[N]; 14 struct Lin{ 15 int next,to,dis,cost; 16 }a[N*N]; 17 int map[101][101]; 18 void init(int x,int y,int dis,int cost){ 19 a[++num].next=head[x]; 20 a[num].to=y; 21 a[num].dis=dis; 22 a[num].cost=cost; 23 head[x]=num; 24 a[++num].next=head[y]; 25 a[num].to=x; 26 a[num].dis=0; 27 a[num].cost=-cost; 28 head[y]=num; 29 } 30 bool vis[N];int q[N*10],pre[N],f[N],ans=0; 31 bool spfa() 32 { 33 for(int i=0;i<=T;i++)f[i]=INF,vis[i]=false; 34 q[1]=S;f[S]=0;int x,u,t=0,sum=1; 35 while(t!=sum) 36 { 37 x=q[++t]; 38 for(int i=head[x];i;i=a[i].next){ 39 u=a[i].to; 40 if(a[i].dis<=0)continue; 41 if(f[x]+a[i].cost<f[u]){ 42 f[u]=f[x]+a[i].cost; 43 pre[u]=i; 44 if(!vis[u])vis[u]=true,q[++sum]=u; 45 } 46 } 47 vis[x]=false; 48 } 49 if(f[T]!=INF) 50 ans+=f[T]; 51 return f[T]!=INF; 52 } 53 void Change() 54 { 55 int x=T; 56 while(x){ 57 a[pre[x]].dis--; 58 a[pre[x]^1].dis++; 59 x=a[pre[x]^1].to; 60 } 61 } 62 void Clear(){ 63 memset(head,0,sizeof(head)); 64 num=1;ans=0; 65 } 66 int main() 67 { 68 n=gi();T=(n<<1)+1; 69 for(int i=1;i<=n;i++)init(S,i,1,0),init(i+n,T,1,0); 70 for(int i=1;i<=n;i++){ 71 for(int j=1;j<=n;j++){ 72 map[i][j]=gi();init(i,j+n,INF,map[i][j]); 73 } 74 } 75 while(spfa()){ 76 Change(); 77 } 78 printf("%d\n",ans); 79 Clear(); 80 for(int i=1;i<=n;i++)init(S,i,1,0),init(i+n,T,1,0); 81 for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)init(i,j+n,INF,-map[i][j]); 82 while(spfa()){ 83 Change(); 84 } 85 printf("%d",-ans); 86 return 0; 87 }