poj2516Minimum Cost

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

建图的时候 有个地方写错了 卡了半年。。

题意看了N久啊 有N个店主需要K种物品 有M个供应点 每个供应点有K种物品 其实是算K次最小费用 然后叠加 分解开来这题就是求把某种物品从供应点送到店主那里

多个源点-》多个汇点  所以加一个超级源点 和 超级汇点 源点->M个供应点->N个店主->汇点 所以共有m+n+2条边 套最小费用模板就行了

View Code
  1 #include <iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<queue>
  6 #define MN 10000
  7 #define MM 10000
  8 #define INF 0xfffffff
  9 using namespace std;
 10 struct node
 11 {
 12     int u,v,cost,cap,next;
 13 }edge[MM];
 14 int head[MN],t,vis[MN],dist[MN],co[55][55][55],sh[55][55],sto[55][55],pp[MN],flow;
 15 void init()
 16 {
 17     t = 0;
 18     memset(head,-1,sizeof(head));
 19 }
 20 void add(int u,int v,int c,int p)
 21 {
 22     edge[t].u = u;
 23     edge[t].v = v;
 24     edge[t].cap = c;
 25     edge[t].cost = p;
 26     edge[t].next = head[u];
 27     head[u] = t++;
 28     edge[t].v = u;
 29     edge[t].u = v;
 30     edge[t].cap = 0;
 31     edge[t].cost = -p;
 32     edge[t].next = head[v];
 33     head[v] = t++;
 34 }
 35 int spfa(int s,int en,int n)
 36 {
 37     int i,j,u,v;
 38     for(i =0 ; i <= n ; i++)
 39     dist[i] = INF;
 40     memset(vis,0,sizeof(vis));
 41     memset(pp,-1,sizeof(pp));
 42     queue<int>q;
 43     q.push(s);
 44     vis[s] = 1;
 45     dist[s] = 0;
 46     while(!q.empty())
 47     {
 48         u = q.front();
 49         q.pop();
 50         vis[u] = 0;
 51         for(i = head[u] ; i != -1 ; i = edge[i].next)
 52         {
 53             v = edge[i].v;
 54             if(edge[i].cap&&dist[v]>dist[u]+edge[i].cost)
 55             {
 56                 dist[v] = dist[u]+edge[i].cost;
 57                 //cout<<dist[v]<<endl;
 58                 pp[v] = i;
 59                 if(!vis[v])
 60                 {
 61                     vis[v] = 1;
 62                     q.push(v);
 63                 }
 64             }
 65         }
 66     }
 67     //cout<<dist[en]<<" ";
 68     if(dist[en]==INF)
 69     return 0;
 70     return 1;
 71 }
 72 int mcmf(int s,int en,int n)
 73 {
 74     int i,minf,minc=0;
 75     while(spfa(s,en,n))
 76     {
 77         minf = INF+1;
 78         for(i = pp[en] ; i != -1 ; i = pp[edge[i].u])
 79         {
 80             if(edge[i].cap<minf)
 81             minf = edge[i].cap;
 82         }
 83         flow+=minf;
 84         for(i = pp[en] ; i != -1 ; i = pp[edge[i].u])
 85         {
 86             edge[i].cap-=minf;
 87             edge[i^1].cap+=minf;
 88         }
 89         minc+=minf*dist[en];
 90     }
 91     return minc;
 92 }
 93 int main()
 94 {
 95     int i,j,n,m,k,g;
 96     while(cin>>n>>m>>k)
 97     {
 98         if(n==0&&m==0&&k==0)
 99         break;
100         int flag = 0,ss=0;
101         for(i = 1; i <= n ; i++)
102             for(j = 1; j <= k ; j++)
103                 cin>>sh[i][j];
104         for(i = 1; i <= m ; i++)
105              for(j = 1; j <= k ; j++)
106                 cin>>sto[i][j];
107         for(i = 1;i <= k ; i++)
108             for(j = 1 ; j <= n ; j++)
109                 for(g = 1; g <= m ; g++)
110                 cin>>co[i][j][g];
111         int s = 0,en = n+m+1;
112         for(i = 1; i <= k ; i++)
113         {
114             init();
115             int sa=0;
116             for(j = 1 ; j <= n ; j++)
117             {
118                add(m+j,en,sh[j][i],0);
119                sa+=sh[j][i];
120             }
121             for(j = 1; j <= m ; j++)
122                 add(s,j,sto[j][i],0);
123             for(j = 1; j <= m ; j++)
124                 for(g = 1 ; g <= n ; g++)
125                     add(j,m+g,INF,co[i][g][j]);
126             flow=0;
127             ss+=mcmf(s,en,n+m+1);
128             if(sa>flow)
129                 break;
130         }
131         if(i==k+1)
132         cout<<ss<<endl;
133         else
134         cout<<"-1\n";
135     }
136     return 0;
137 }
原文地址:https://www.cnblogs.com/shangyu/p/2972399.html