分配问题
Description
有
n
件工作要分配给
第
i
个人做第
试设计一个将
n
件工作分配给
对于给定的
n
件工作和
Input
文件的第
1
行有
接下来的
第
Output
程序运行结束时,将计算出的最小总效益和最大总效益输出到文件。
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
Solution
第一次打费用流的题目。
本题建模很容易看出来,就只是加一个源点和汇点。
至于两个要求,就分别求出最小费用流和最大费用流即可。
Code
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <queue>
- #define INF 0x3f3f3f3f
- #define MAXN (250)
- #define ss 0
- #define tt 220
- #define Min(x,y) ((x)<(y)?(x):(y))
- using namespace std;
- int n,cnt,ans;
- int head[MAXN],nxt[MAXN*MAXN*2],data[MAXN*MAXN*2],flow[MAXN*MAXN*2],wei[MAXN*MAXN*2];
- int flow2[MAXN*MAXN*2];
- int pre[MAXN],dis[MAXN];
- bool in_stack[MAXN];
- queue<int>q;
- void add(int x,int y,int z,int W){
- nxt[cnt]=head[x];data[cnt]=y;flow[cnt]=z;wei[cnt]=W;head[x]=cnt++;
- nxt[cnt]=head[y];data[cnt]=x;flow[cnt]=0;wei[cnt]=-W;head[y]=cnt++;
- }
- bool BFS1(){
- memset(dis,0x3f,sizeof dis);
- dis[ss]=0;in_stack[ss]=true;
- q.push(ss);pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- int now=q.front();q.pop();in_stack[now]=false;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(flow[i]&&dis[data[i]]>dis[now]+wei[i]){
- dis[data[i]]=dis[now]+wei[i];
- pre[data[i]]=i^1;
- if(!in_stack[data[i]]){
- in_stack[data[i]]=true;
- q.push(data[i]);
- }
- }
- }
- }
- return dis[tt]<INF&&pre[tt]>0;
- }
- bool BFS2(){
- memset(dis,-INF,sizeof dis);
- dis[ss]=0;in_stack[ss]=true;
- q.push(ss);pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- int now=q.front();q.pop();in_stack[now]=false;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(flow2[i]&&dis[data[i]]<dis[now]+wei[i]){
- dis[data[i]]=dis[now]+wei[i];
- pre[data[i]]=i^1;
- if(!in_stack[data[i]]){
- in_stack[data[i]]=true;
- q.push(data[i]);
- }
- }
- }
- }
- return pre[tt]>0;
- }
- void dfs1(){
- int Low=INF;
- for(int i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow[i^1]);
- for(int i=pre[tt];i!=-1;i=pre[data[i]]){flow[i]+=Low;flow[i^1]-=Low;}
- }
- void dfs2(){
- int Low=INF;
- for(int i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow2[i^1]);
- for(int i=pre[tt];i!=-1;i=pre[data[i]]){flow2[i]+=Low;flow2[i^1]-=Low;}
- }
- int main(){
- memset(head,-1,sizeof head);
- scanf(”%d”,&n);
- for(int i=1;i<=n;i++){
- add(ss,i,1,0);
- add(i+n,tt,1,0);
- for(int j=1;j<=n;j++){
- int x;scanf(“%d”,&x);
- add(i,j+n,1,x);
- }
- }
- memcpy(flow2,flow,sizeof flow);
- ans=0;
- while(BFS1())dfs1();
- for(int i=0;i<cnt;i++)if(data[i]>=n+1&&data[i]<=n+n&&!flow[i])ans+=wei[i];
- printf(”%d\n”,ans);
- ans=0;
- while(BFS2())dfs2();
- for(int i=0;i<cnt;i++)if(data[i]>=n+1&&data[i]<=n+n&&!flow2[i])ans+=wei[i];
- printf(”%d\n”,ans);
- return 0;
- }