Minimum Cost—-最小費用流

來源:互聯網
上載者:User

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

原始碼:

#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#define INF 1e9#define MAXN 110const int N = 200, M = 10010;using namespace  std;int n,m,k,ans;int cost[MAXN][MAXN][MAXN];int need[MAXN][MAXN],sale[MAXN][MAXN];int sasum[MAXN],nesum[MAXN];struct MinCostMaxFlow {    int e, ev[M], nxt[M], head[N];    int  cost[M], dist[N];    int cap[M];    int pnt[N], road[N], q[N], bg, ed;    bool vis[N]; void init(int n) {   e = 0;   for(int i=0;i<=n;i++)    head[i]=-1;  } void addedge(int u, int v, int f, int  c) { //u->v flow=f, cost=c   ev[e]=v; cap[e]=f; cost[e]=c; nxt[e]=head[u]; head[u]=e++;   ev[e]=u; cap[e]=0; cost[e]=-c; nxt[e]=head[v]; head[v]=e++;   } bool spfa(int s, int t, int n) {     for(int i=0;i<=n;i++)  {  dist[i]=INF;  vis[i]=0; }     bg = ed = dist[s] = 0;     pnt[s] = s; q[ed++] = s;     while (bg != ed) {         int u = q[bg++]; vis[u] = 0;         if (bg == N) bg = 0;         for (int i = head[u]; ~i; i = nxt[i]) {            if (cap[i] <= 0)  continue;            int v = ev[i];            if (dist[v] > dist[u] + cost[i]) {                dist[v] = dist[u] + cost[i];                pnt[v] = u; road[v] = i;            if (!vis[v]) {                q[ed++] = v; vis[v] = 1;                if(ed == N)ed = 0;                }            }        }    }    return dist[t] != INF;} void mincost(int s, int t, int n, int &f, int  &c) {        c = f = 0;        while(spfa(s, t, n)){            int minf = INF;            for(int u = t; u != s; u = pnt[u])                minf = min(minf, cap[road[u]]);                for(int u = t; u != s; u = pnt[u]){                    cap[road[u]] -= minf;                    cap[road[u] ^ 1] += minf;                    }                f += minf;                c += minf * dist[t];            }    }};int solve(int x){    MinCostMaxFlow ans;    int ans1,ans2;    ans.init(m+n+1);    for(int i=1;i<=m;i++)    ans.addedge(0,i,sale[i][x],0);    for(int i=1;i<=m;i++)      for(int j=1;j<=n;j++)    ans.addedge(i,j+m,INF,cost[x][j][i]);    for(int i=1;i<=n;i++)    ans.addedge(m+i,m+n+1,need[i][x],0);    ans.mincost(0,m+n+1,m+n+2,ans1,ans2);    return ans2;}int  main(){   // freopen("D:\\a.txt","r",stdin);  while(true)  {      memset(sasum,0,sizeof(sasum));      memset(nesum,0,sizeof(nesum));      scanf("%d %d %d",&n,&m,&k);      if(!n&&!m&&!k)  break;      for(int i=1;i<=n;i++)      {          for(int j=1;j<=k;j++)          {              scanf("%d",&need[i][j]);              nesum[j]+=need[i][j];          }      }      for(int i=1;i<=m;i++)      {          for(int j=1;j<=k;j++)          {              scanf("%d",&sale[i][j]);              sasum[j]+=sale[i][j];          }      }    for(int p=1;p<=k;p++)      for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)         scanf("%d",&cost[p][i][j]);    int flag=1;    for(int i=1;i<=k;i++)     if(sasum[i]<nesum[i])     {         printf("-1\n");         flag=0;        break;     }     if(!flag)  continue;      ans=0;      for(int i=1;i<=k;i++)      {          int tmp=solve(i);             ans+=tmp;      }      if(flag)  printf("%d\n",ans);  }  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.