多源多汇费用流——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的主要内容,如果未能解决你的问题,请参考以下文章

poj1459网络流之多源点最大流

POJ2516 Minimum Cost最小费用最大流

Minimum Cost POJ - 2516 (模板题 spfa最小费用最大流)

POJ2516

Maven配置多源代码目录多资源目录

Maven配置多源代码目录多资源目录