網絡流24題-分配問題
阿新 • • 發佈:2018-08-26
names != false 輸出 ora hit sample bit bottom
輸出樣例:
二分圖多重最優匹配。
分配問題
時空限制1000ms / 256MB
題目描述
有 n 件工作要分配給 n 個人做。第 i 個人做第 j 件工作產生的效益為 c[i][j]。試設計一個將 n 件工作分配給 n 個人做的分配方案,使產生的總效益最大。
輸入輸出格式
輸入格式:文件的第 1 行有 1 個正整數 n ,表示有 n 件工作要分配給 n 個人做。
接下來的 n 行中,每行有 n 個整數 c??,表示第 i 個人做第 j 件工作產生的效益為 c[i][j]? 。
輸出格式:兩行分別輸出最小總效益和最大總效益。
輸入輸出樣例
輸入樣例: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
5 14
說明
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,intView Codev,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); longlong 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; }
網絡流24題-分配問題