POJ2516 Minimum Cost(K次费用流)

来源:互联网 发布:手机淘宝联盟自己购买 编辑:程序博客网 时间:2024/05/01 08:31

链接:http://poj.org/problem?id=2516
题意太麻烦了,看懂题意之后就很简单了。。。不解释题意了。。。
思路:事先判断一下物品够不够。然后对每个物品建图跑费用流。建图的时候要小心,容易写错。
直接上代码吧

#include<cstdio>#include<cstring>#include<string>#include<queue>#include<map>#include<iostream>#include<vector>#include<cstdlib>#include<cmath>#include<stack>#include<cctype>#include<set>#include<ctime>#include<cassert>#include<algorithm>using namespace std;typedef long long ll;typedef pair<int,int> pii;const int INF=1e9+7;#define MP make_pair#define PB push_backstruct node{    int cap,cost;}G[110][110];int n,m,k,st,ed,need[55][55],save[55][55],pic[55][55][55];int d[110],pre[110],flow[110];bool vis[110];void input(){    for(int i=1;i<=n;i++){        for(int j=1;j<=k;j++){            scanf("%d",&need[i][j]);//need[n][k]        }    }    for(int i=1;i<=m;i++){        for(int j=1;j<=k;j++){            scanf("%d",&save[i][j]);//save[m][k]        }    }    for(int w=1;w<=k;w++){        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                scanf("%d",&pic[w][i][j]);//pic[k][n][m]            }        }    }}bool check(){//判断一下是否不够    for(int w=1;w<=k;w++){        int sum=0;        for(int i=1;i<=m;i++){            sum+=save[i][w];        }        for(int i=1;i<=n;i++){            sum-=need[i][w];        }        if(sum<0)return false;    }    return true;}void build(int w){//对每一个物品建图    memset(G,0,sizeof G);    st=0;ed=n+m+1;    //st->m cap:save[m][w] cost:0    //n->ed cap:need[n][w] cost:0    for(int i=1;i<=n;i++){        G[i+m][ed].cap=need[i][w];    }    for(int j=1;j<=m;j++){        G[st][j].cap=save[j][w];    }    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            G[j][i+m].cap=save[j][w];            G[j][i+m].cost=pic[w][i][j];            G[i+m][j].cost=-pic[w][i][j];        }    }}bool spfa(int &ff,int &ans){    queue<int> Q;    Q.push(st);    fill(d,d+ed+1,INF);    d[st]=0;vis[st]=true;flow[st]=INF;pre[st]=-1;    while(!Q.empty()){        int s=Q.front();Q.pop();        vis[s]=false;        for(int i=1;i<=ed;i++){            if(G[s][i].cap>0&&d[i]>d[s]+G[s][i].cost){                d[i]=d[s]+G[s][i].cost;                pre[i]=s;                flow[i]=min(flow[s],G[s][i].cap);                if(!vis[i]){                    vis[i]=true;Q.push(i);                }            }        }    }    if(d[ed]==INF)return false;    ff+=flow[ed];ans+=flow[ed]*d[ed];    int now=ed;    while(now!=st){        G[pre[now]][now].cap-=flow[ed];        G[now][pre[now]].cap+=flow[ed];        now=pre[now];    }    return true;}int main(){//    freopen("D://input.txt","r",stdin);    while(scanf("%d%d%d",&n,&m,&k)!=EOF&&n&&m&&k){        input();        if(!check()){printf("-1\n");continue;}        int ff=0,ans=0;        for(int w=1;w<=k;w++){            build(w);            while(spfa(ff,ans));//printf("%d %d\n",ff,ans);        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击