POJ 2516 Minimum Cost(最小費用最大流,坑題)

來源:互聯網
上載者:User

標籤:style   http   color   os   io   strong   for   資料   

題目連結:http://poj.org/problem?id=2516


題意:有N個店,M個供貨商,K種商品。已知供貨商的倉庫裡每種商品的數量以及每種商品運送到每個店的費用,每個店鋪對各種商品的需求數量,求最少話費。 

Input 

第一行:N,M,K。
然後1 - N行,每行 K列 ,第I行第J個數代表 第I個店鋪 需要第J種物品多少件。
然後 N+1 - M行  ,每行 K列 , 第I行第J個數代表 第I個供貨商 有第J種物品多少件。
然後是K個矩陣  ,每個N行M列,第ji個矩陣的第i行第j列代表著第j個供貨商給第i個店鋪發第ji種貨物一件需要的費用。哎喲,我日

坑題一道啊,感覺已經不是在考查網路流,而是在考察對 繁瑣資料輸入 的Debug能力,弄了一上午,坑我啊。。。


思路:一開始思路就是錯的,上去就拆點,將供貨商和店鋪對應著K種商品,把每個供貨商拆成K個,店鋪拆成K個,寫了一半感覺不對勁,50*50 + 50*50 + 50,肯定逾時。

    既然拆點不行,那麼就拆網唄。。。把對應所有商品的整個網路,拆成K個單種商品的網路,求出單個商品的最小費用,最後進行累加即可


建圖:

增設兩個點,源點s = 0,匯點t = N+M+1,源點與供貨商相連,費用0,容量為當前單種商品的供給量

供貨商與店鋪相連費用已知,容量為正無窮。

店鋪與匯點相連,費用0,容量為當前單種商品的需求。


#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>const int maxn = 110;const int maxm = 10000;const int inf = 1e8;#define MIN INT_MIN#define MAX 1e6#define LL long long#define init(a) memset(a,0,sizeof(a))#define FOR(i,a,b) for(int i = a;i<b;i++)#define max(a,b) (a>b)?(a):(b)#define min(a,b) (a>b)?(b):(a)using namespace std;struct node{    int u,v,w,cap,next;}edge[maxm];int pre[maxn],dis[maxn],head[maxn],cnt;bool vis[maxn];int n,m;void add(int u,int v,int c,int cap){    edge[cnt].u=u;    edge[cnt].v=v;    edge[cnt].w=c;    edge[cnt].cap=cap;    edge[cnt].next=head[u];    head[u]=cnt++;    edge[cnt].u=v;    edge[cnt].v=u;    edge[cnt].w=-c;    edge[cnt].cap=0;    edge[cnt].next=head[v];    head[v]=cnt++;}int spfa(int s,int t){    queue<int>q;    while(q.empty()==false) q.pop();    q.push(s);    memset(vis,0,sizeof(vis));    memset(pre,-1,sizeof(pre));    FOR(i,s,t+1)        dis[i] = inf;    dis[s]=0;    while(!q.empty())    {       int u=q.front();        q.pop();        vis[u] = 0;        for(int i=head[u];i!=-1;i=edge[i].next)        {            if(edge[i].cap && dis[edge[i].v]>dis[u]+edge[i].w)            {                dis[edge[i].v]=dis[u]+edge[i].w;                pre[edge[i].v] = i;                if(!vis[edge[i].v])                {                    vis[edge[i].v]=1;                    q.push(edge[i].v);                }            }        }    }    if(dis[t] != inf)        return 1;    else        return 0;}int MinCostMaxFlow(int s,int t){int flow=0,cost=0;    while(spfa(s,t))    {int df = inf;for(int i = pre[t];i!=-1;i=pre[edge[i].u]){if(edge[i].cap<df)df = edge[i].cap;}flow += df;        for(int i=pre[t];i!=-1;i=pre[edge[i].u])        {            edge[i].cap -= df;            edge[i^1].cap += df;        }cost += dis[t] * df;    }    return cost;}void initt(){    cnt=0;    memset(head,-1,sizeof(head));}int main(){    int gong[51],qiu[51];    int k,s,t;    int need[200][200],gei[200][200];    while(scanf("%d%d%d",&n,&m,&k),n,m,k)    {        init(need);init(gei);        init(gong);init(qiu);        s = 0,t = n+m+1;        FOR(i,1,n+1)        {            FOR(j,1,k+1)                {                    scanf("%d",&need[i][j]);                    qiu[j] += need[i][j];                }        }        FOR(i,1,m+1)        {            FOR(j,1,k+1)            {                scanf("%d",&gei[i][j]);                gong[j] += gei[i][j];            }        }        bool flag = 1;        FOR(i,1,k+1)        {            if(gong[i]<qiu[i])//如果單種商品的供給量不滿足該商品的需求量,直接列印-1            {                flag = 0;                break;            }        }        int cost,yao,money = 0;        FOR(ji,1,k+1)        {             initt();                      FOR(i,1,n+1)             {                FOR(j,1,m+1)               {                   scanf("%d",&cost);                   if(flag==0) continue;                   add(j,m+i,cost,inf);//供給商和店主的流量為正無窮               }             }             if(flag==0) continue;             FOR(i,1,n+1)             {                 add(m+i,t,0,need[i][ji]);//店鋪和匯點的費用為0,流量為店對該種商品的需求             }             FOR(i,1,m+1)             {                 add(s,i,0,gei[i][ji]);//源點對供應商的費用為0,流量為供貨商對該種商品的供給             }           money += MinCostMaxFlow(s,t);        }        (flag==0)?puts("-1"):printf("%d\n",money);    }    return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.