分配问题(cogs 740)

«问题描述:

有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为c[i][j]  。试设计一个将
n件工作分配给n个人做的分配方案,使产生的总效益最大。

«编程任务:

对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。

«数据输入:

由文件job.in提供输入数据。

文件的第1 行有1 个正整数n,表示有n件工作要分配给n 个人做。

接下来的n 行中,每行有n 个整数c[i][j] ,1≤i≤n,1≤j≤n,

表示第i 个人做第j件工作产生的效益为c[i][j] 。

«结果输出:

程序运行结束时,将计算出的最小总效益和最大总效益输出到文件job.out中。
输入文件示例 输出文件示例
job.in

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

job.out

5

14

数据范围

N<=100

/*
    简单的费用流。 
*/ 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 210
#define inf 1000000000
using namespace std;
int a[N][N],head[N],dis[N],inq[N],fa[N],n,S,T,cnt=1,ans;
struct node{int v,f,w,pre;}e[N*N*4];
queue<int> q;
void add(int u,int v,int f,int w){
    e[++cnt].v=v;e[cnt].f=f;e[cnt].w=w;e[cnt].pre=head[u];head[u]=cnt;
    e[++cnt].v=u;e[cnt].f=0;e[cnt].w=-w;e[cnt].pre=head[v];head[v]=cnt;
}
bool spfa(){
    for(int i=0;i<=T;i++) dis[i]=inf;
    q.push(S);dis[S]=0;
    while(!q.empty()){
        int u=q.front();q.pop();inq[u]=0;
        for(int i=head[u];i;i=e[i].pre)
            if(e[i].f&&dis[e[i].v]>dis[u]+e[i].w){
                dis[e[i].v]=dis[u]+e[i].w;
                fa[e[i].v]=i;
                if(!inq[e[i].v]){
                    q.push(e[i].v);
                    inq[e[i].v]=1;
                }
            }
    }
    return dis[T]!=inf;
}
void updata(){
    int i=fa[T],x=inf;
    while(i){
        x=min(x,e[i].f);
        i=fa[e[i^1].v];
    }
    i=fa[T];
    while(i){
        e[i].f-=x;
        e[i^1].f+=x;
        i=fa[e[i^1].v];
    }
    ans+=x*dis[T];
}
void work(int fl){
    memset(head,0,sizeof(head));
    S=0;T=n*2+1;cnt=1;ans=0;
    for(int i=1;i<=n;i++)
        add(S,i,1,0),add(i+n,T,1,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            add(i,j+n,1,a[i][j]*fl);
    while(spfa())
        updata();
    printf("%d\n",ans*fl);
}
int main(){
    freopen("job.in","r",stdin);
    freopen("job.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&a[i][j]);
    work(1);work(-1);
    return 0;
}

 

posted @ 2017-04-14 22:11  karles~  阅读(177)  评论(0编辑  收藏  举报