多源多汇费用流——poj2516
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多源多汇费用流——poj2516相关的知识,希望对你有一定的参考价值。
网络流的题好难。。感觉有点遭不住了
这题用矩阵存图,然后把k个物品,每个物品都求一次费用流
/* 多源多汇的费用流 其实是k个费用流 */ #include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define maxn 205 struct Edgeint to,nxt,w,c;e[maxn<<2]; int head[maxn],tot,n,m,s,t; void init() void add(int u,int v,int w,int c) int sum_need[maxn],sum_offer[maxn]; int offer[maxn][maxn],need[maxn][maxn],mp[maxn][maxn],cost[maxn][maxn],K,sum,pre[maxn]; int dis[maxn],vis[maxn]; int spfa() queue<int>q; for(int i=0;i<=t;i++)vis[i]=false;dis[i]=inf; vis[s]=1;dis[s]=0;q.push(s); while(!q.empty()) int k=q.front();q.pop();vis[k]=false; for(int i=0;i<=t;i++) if(mp[k][i] && dis[i]>dis[k]+cost[k][i]) dis[i]=dis[k]+cost[k][i]; pre[i]=k; if(!vis[i]) vis[i]=1; q.push(i); if(dis[t]!=inf)return 1; return 0; int fond() int Min=inf,res=0; while(spfa()) for(int i=t;i!=s;i=pre[i]) Min=min(Min,mp[pre[i]][i]); for(int i=t;i!=s;i=pre[i]) mp[pre[i]][i]-=Min; mp[i][pre[i]]+=Min; res+=cost[pre[i]][i]*Min; return res; int main() while(cin>>n>>m>>K,n&&m&&K) sum=0; memset(sum_need,0,sizeof sum_need); memset(sum_offer,0,sizeof sum_offer); for(int i=1;i<=n;i++) for(int j=1;j<=K;j++) scanf("%d",&need[i][j]); sum_need[j]+=need[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=K;j++) scanf("%d",&offer[i][j]); sum_offer[j]+=offer[i][j]; int sign=0; for(int i=1;i<=K;i++) if(sum_offer[i]<sum_need[i]) sign=1; break; s=0; t=n+m+1; for(int k=1;k<=K;k++) memset(mp,0,sizeof mp); memset(cost,0,sizeof cost); //第k件物品 供应商->店主的运费 for(int i=1+m;i<=n+m;i++) for(int j=1;j<=m;j++) scanf("%d",&cost[j][i]); cost[i][j]-=cost[j][i];//反向边的费用 if(sign==1)continue; for(int i=1;i<=m;i++)//s->供应商 mp[s][i]=offer[i][k]; for(int i=1;i<=m;i++)//供应商->店主 for(int j=m+1;j<=m+n;j++) mp[i][j]=offer[i][k]; for(int i=m+1;i<=m+n;i++)//店主->t mp[i][t]=need[i-m][k]; sum+=fond(); if(sign==1) printf("-1\n"); else printf("%d\n",sum);
以上是关于多源多汇费用流——poj2516的主要内容,如果未能解决你的问题,请参考以下文章