时空限制1000ms / 256MB
题目描述
有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为 c[i][j]。试设计一个将 n 件工作分配给 n 个人做的分配方案,使产生的总效益最大。
输入输出格式
输入格式:文件的第 1 行有 1 个正整数 n ,表示有 n 件工作要分配给 n 个人做。
接下来的 n 行中,每行有 n 个整数 c,表示第 i 个人做第 j 件工作产生的效益为 c[i][j] 。
输出格式:两行分别输出最小总效益和最大总效益。
输入输出样例
说明
1≤n≤100
一个人只能做一个工作
二分图多重最优匹配。
感觉就是费用流,只不过知道模型容易建图了一些。
#include<bits/stdc++.h> #define N 505 #define INF LLONG_MAX/2 using namespace std; typedef struct { int u,v; long long flow,cost; }ss; ss edg[N*N]; vector<int>edges[N]; int now_edges=0; void addedge(int u,int v,long long flow,long long cost) { edges[u].push_back(now_edges); edg[now_edges++]=(ss){u,v,flow,cost}; edges[v].push_back(now_edges); edg[now_edges++]=(ss){v,u,0,-cost}; } bool spfa(int s,int t,long long &flow,long long &cost) { // printf("%lld %lld\n",flow,cost); long long dis[N]; for(int i=0;i<N;i++)dis[i]=INF; dis[s]=0; int vis[N]={0}; vis[s]=1; queue<int>q; q.push(s); int pre[N]={0}; long long maxflow[N]={0}; maxflow[s]=INF; while(!q.empty()) { int now=q.front(); q.pop(); vis[now]=0; int Size=edges[now].size(); for(int i=0;i<Size;i++) { ss &e=edg[edges[now][i]]; if(e.flow>0&&dis[e.v]>dis[now]+e.cost) { dis[e.v]=dis[now]+e.cost; pre[e.v]=edges[now][i]; maxflow[e.v]=min(maxflow[now],e.flow); if(!vis[e.v]) { q.push(e.v); vis[e.v]=1; } } } } if(dis[t]==INF)return false; flow+=maxflow[t]; cost+=dis[t]*maxflow[t]; long long now=t; while(now!=s) { edg[pre[now]].flow-=maxflow[t]; edg[pre[now]^1].flow+=maxflow[t]; now=edg[pre[now]].u; } return true; } void mcmf(int s,int t,long long &flow,long long &cost) { while(spfa(s,t,flow,cost)); } void init() { now_edges=0; for(int i=0;i<N;i++)edges[i].clear(); } int c[505][505]; int main() { int n,s,t; scanf("%d",&n); s=2*n+1; t=2*n+2; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&c[i][j]); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)addedge(i,j+n,1,c[i][j]); for(int i=1;i<=n;i++) { addedge(s,i,1,0); addedge(i+n,t,1,0); } long long flow=0,cost=0; mcmf(s,t,flow,cost); printf("%lld\n",cost); init(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)addedge(i,j+n,1,-c[i][j]); for(int i=1;i<=n;i++) { addedge(s,i,1,0); addedge(i+n,t,1,0); } flow=0; cost=0; mcmf(s,t,flow,cost); printf("%lld\n",-cost); return 0; }
来源:https://www.cnblogs.com/tian-luo/p/9536140.html