POJ 2516 Minimum Cost(最小费用最大流)

来源:互联网 发布:ipad air2软件下载 编辑:程序博客网 时间:2024/05/19 12:24

题目链接
这题也是裸的暴力枚举最小费用最大流。
题目意思:有n个供应商,m个客户,k种物品,分别给出每个客户对物品的需求量,商家对物品的供给量,和费用,求能否满足每一个人的要求如果可以输出最小费用。
可以建k次图,枚举物品求最小费用最大流。
建图:
源点 到 商家 流量为存货量,费用为0
客户 到 汇点 流量为需求 ,费用为 0
商家 到客户 流量为inf ,费用为 题目所给
跑最小费用最大流 加一个maxflow变量就可以解决判断需求量的问题

#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define MAXN 1005#define INF 2000000000int source,sink;struct tree{    int from,to,flow,worth,next;    tree(){}    tree(int fr,int ro,int fl,int wo,int ne)    {        from=fr,to=ro,flow=fl,worth=wo,next=ne;    }}e[MAXN*MAXN];int g[MAXN];int num;int maxflow;    //用于记录最大流是否满足需求量void init(){    memset(g,0,sizeof(g));    num=1;    maxflow=0;}void addtree(int from,int to,int flow,int worth){    e[++num]=tree(from,to,flow,worth,g[from]);    g[from]=num;    e[++num]=tree(to,from,0,-worth,g[to]);    g[to]=num;}bool visque[MAXN];int dis[MAXN];int pre[MAXN],prx[MAXN];queue<int>q;int bfs(){    while(!q.empty()) q.pop();    for(int i=0;i<=MAXN;i++)    dis[i]=INF;    q.push(source);    dis[source]=0;    visque[source]=true;    while(!q.empty())    {        int u=q.front();        q.pop();        for(int i=g[u];i;i=e[i].next)        {            if(e[i].flow>0&&dis[u]+e[i].worth<dis[e[i].to])            {                dis[e[i].to]=dis[u]+e[i].worth;                pre[e[i].to]=u;                prx[e[i].to]=i;                if(!visque[e[i].to])                {                    visque[e[i].to]=true;                    q.push(e[i].to);                }            }        }        visque[u]=false;    }    return dis[sink]!=INF;}int dfs(){    int u=sink;    int ans=INF;    while(u!=source)    {        if(e[prx[u]].flow<ans) ans=e[prx[u]].flow;        u=pre[u];    }    u=sink;    while(u!=source)    {        e[prx[u]].flow-=ans;        e[prx[u]^1].flow+=ans;        u=pre[u];    }    maxflow+=ans;    return ans*dis[sink];}int solve(){    int cur=0;    int ans=0;    while(bfs())    {        cur+=dfs();        if(cur>ans) ans=cur;    }    return ans;}int nn[200][200];int mm[200][200];int wor[200][200][200];int main(){    int n,m,k;    while(scanf("%d%d%d",&n,&m,&k)==3,n+m+k)    {        source=1;sink=1000;        for(int i=0;i<n;i++)            for(int j=0;j<k;j++)                scanf("%d",&nn[i][j]);        for(int i=0;i<m;i++)            for(int j=0;j<k;j++)                scanf("%d",&mm[i][j]);        for(int l=0;l<k;l++)            for(int i=0;i<n;i++)                for(int j=0;j<m;j++)                    scanf("%d",&wor[l][i][j]);        int ans=0;        int flag=1;        for(int i=0;flag&&i<k;i++)        {            init();            int need=0;            for(int j=0;j<n;j++)            {                addtree(j+102,sink,nn[j][i],0);                need+=nn[j][i];            }            for(int j=0;j<m;j++)                addtree(source,j+2,mm[j][i],0);            for(int l=0;l<n;l++)                for(int j=0;j<m;j++)                    addtree(j+2,l+102,INF,wor[i][l][j]);            ans+=solve();            if(need!=maxflow)flag=false;        }        if(flag)printf("%d\n",ans);        else printf("-1\n");    }}
0 0