1. 程式人生 > >網絡流24題-分配問題

網絡流24題-分配問題

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

說明

1n100

一個人只能做一個工作


二分圖多重最優匹配。

感覺就是費用流,只不過知道模型容易建圖了一些。 技術分享圖片
#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; }
View Code

網絡流24題-分配問題