POJ 2516 最小費用流

做的第一個最小費用流問題,第一次忘了費用乘以流量 WA了一次,每次輸入一個矩陣都運行一次最小費用流即可。

 

 

#include<iostream>

#include<cstring>

#include<queue>

#include<cstdio>

using namespace std;

 

#define INF 0x1f1f1f1f

#define MIN(a,b) ((a)<(b)?(a):(b))

 

int store[60][60];//儲量

int book[60][60];//訂購量

 

int cost[200][200]; //花費

int flow[200][200]; //流量

int cap[200][200];  //容量

#define SIZE 200   //圖大小

 

void cost_flow(int& max_flow,int& min_cost,int st,int ed,int src,int tar)

{

       int pre[SIZE];

       int dis[SIZE];

       bool fl[SIZE];

       while(1)

       {

              memset(pre,-1,sizeof(pre));

              memset(dis,0x1f,sizeof(dis));

              memset(fl,0,sizeof(fl));

              queue<int>q;

              q.push(src);

              dis[src]=0;

//使用Bellman_ford尋找增廣路及最短距離

              while(!q.empty())

              {

                     int u=q.front();

                     q.pop();

                     fl[u]=0;

                     for(int i=st;i<=ed;i++)

                     {

                            if(cap[u][i]>flow[u][i]&&dis[u]+cost[u][i]<dis[i])

                            {

                                   dis[i]=dis[u]+cost[u][i];

                                   pre[i]=u;

                                   if(!fl[i])

                                   {

                                          fl[i]=1;

                                          q.push(i);

                                   }

                            }

                     }

              }

//

              if(pre[tar]==-1)break;

              int min=INF;

              for(int i=tar;pre[i]!=-1;i=pre[i])

              {

                     min=MIN(min,cap[pre[i]][i]-flow[pre[i]][i]);

              }

              for(int i=tar;pre[i]!=-1;i=pre[i])

              {

                     flow[pre[i]][i]+=min;

                     flow[i][pre[i]]-=min;

              }

              max_flow+=min;

              min_cost+=min*dis[tar];

       }

}

 

int main()

{

       int n,m,k;

       while(~scanf("%d%d%d",&n,&m,&k),n||k||m)

       {

              for(int i=0;i<n;i++)

              {

                     for(int j=0;j<k;j++)

                     {

                            scanf("%d",&book[i][j]);

                     }

              }

              for(int i=0;i<m;i++)

              {

                     for(int j=0;j<k;j++)

                     {

                            scanf("%d",&store[i][j]);

                     }

              }

              int res=0;

              for(int p=0;p<k;p++)

              {

                     memset(cost,0,sizeof(cost));

                     for(int i=1;i<=n;i++)

                     {

                            for(int j=1;j<=m;j++)

                            {

                                   scanf("%d",&cost[j][i+m]);

                                   cost[i+m][j]=-cost[j][i+m];

                            }

                     }

                     memset(cap,0,sizeof(cap));

                     memset(flow,0,sizeof(flow));

                     for(int i=1;i<=m;i++)

                     {

                            cap[0][i]=store[i-1][p];

                     }

                     for(int i=1;i<=n;i++)

                     {

                            cap[m+i][m+n+1]=book[i-1][p];

                     }

                     for(int i=1;i<=m;i++)

                     {

                            for(int j=1;j<=n;j++)

                            {

                                   cap[i][m+j]=store[i-1][p];

                            }

                     }

                     int flow=0;

                     int cos=0;

                     int cnt=0;

                     for(int i=0;i<n;i++)

                     {

                            cnt+=book[i][p];

                     }

                     cost_flow(flow,cos,0,m+n+1,0,m+n+1);

                     if(flow!=cnt)

                     {

                            res=-1;

                     }

                     else if(res!=-1)

                     {

                            res+=cos;

                     }

              }

              printf("%d\n",res);

       }

       return 0;

}

發佈了44 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章