题目描述 Description
有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为ij c 。试设计一个将
n件工作分配给n个人做的分配方案,使产生的总效益最大。
«编程任务:
对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。
输入描述 Input Description
第1 行有1 个正整数n,表示有n件工作要分配给n 个人做。接下来的n 行中,每行有n 个整数 cij ,1≤i≤n,1≤j≤n,表示第i 个人做第j件工作产生的效益为cij
输出描述 Output Description
将计算出的最小总效益和最大总效益输出
样例输入 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
又是一道无数据范围的题目,无语了,开了2000
这是道裸题吧,S向左边流量为1,费用为0,
左边向右边,流量为1,费用a[i][j],
右边向汇点,流量为1,费用为0。
1 #include<cstring> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdio> 6 #include<queue> 7 8 #define N 2007 9 #define M 1000007 10 #define inf 1000000007 11 using namespace std; 12 inline int read() 13 { 14 int x=0,f=1;char ch=getchar(); 15 while(ch>‘9‘||ch<‘0‘){if (ch==‘-‘) f=-1;ch=getchar();} 16 while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();} 17 return x*f; 18 } 19 20 int n,S,T; 21 int cnt=1,head[N],rea[M],val[M],cost[M],next[M]; 22 int dis[N],flag[N],a[N][N]; 23 struct Node 24 { 25 int e,fa; 26 void init(){e=fa=-1;} 27 }pre[N]; 28 29 void add(int u,int v,int fee,int pay) 30 { 31 next[++cnt]=head[u]; 32 head[u]=cnt; 33 rea[cnt]=v; 34 val[cnt]=fee; 35 cost[cnt]=pay; 36 } 37 void build(int k) 38 { 39 cnt=1,memset(head,-1,sizeof(head)); 40 for (int i=1;i<=n;i++) 41 add(S,i,1,0),add(i,S,0,0); 42 for (int i=1;i<=n;i++) 43 add(i+n,T,1,0),add(T,i+n,0,0); 44 for (int i=1;i<=n;i++) 45 for (int j=1;j<=n;j++) 46 add(i,j+n,1,a[i][j]*k),add(j+n,i,0,-a[i][j]*k); 47 } 48 bool Spfa() 49 { 50 for (int i=S;i<=T;i++) 51 dis[i]=inf,flag[i]=0,pre[i].init(); 52 queue<int>q;q.push(S); 53 dis[S]=0,flag[S]=1; 54 while(!q.empty()) 55 { 56 int u=q.front();q.pop(); 57 for (int i=head[u];i!=-1;i=next[i]) 58 { 59 int v=rea[i],fee=cost[i]; 60 if ((dis[v]>dis[u]+fee)&&val[i]>0) 61 { 62 dis[v]=dis[u]+fee; 63 pre[v].e=i,pre[v].fa=u; 64 if (!flag[v]) 65 { 66 flag[v]=1; 67 q.push(v); 68 } 69 } 70 } 71 flag[u]=0; 72 } 73 if (dis[T]==inf) return 0; 74 else return 1; 75 } 76 int mfmc() 77 { 78 int flow=0,res=0; 79 while(Spfa()) 80 { 81 int x=inf; 82 for (int i=T;pre[i].fa!=-1;i=pre[i].fa) 83 { 84 int e=pre[i].e; 85 x=min(x,val[e]); 86 } 87 flow+=x,res+=dis[T]*x; 88 for (int i=T;pre[i].fa!=-1;i=pre[i].fa) 89 { 90 int e=pre[i].e; 91 val[e]-=x,val[e^1]+=x; 92 } 93 } 94 return res; 95 } 96 int main() 97 { 98 n=read(),S=0,T=n*2+1; 99 for (int i=1;i<=n;i++) 100 for (int j=1;j<=n;j++) 101 a[i][j]=read(); 102 build(1);printf("%d\n",mfmc()); 103 build(-1);printf("%d\n",-mfmc()); 104 }