多源多汇费用流——poj2516

网络流的题好难。。感觉有点遭不住了

这题用矩阵存图,然后把k个物品,每个物品都求一次费用流

/*
多源多汇的费用流
其实是k个费用流
*/
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 205
struct Edge{int 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);
    }
}

原文地址:https://www.cnblogs.com/zsben991126/p/11000716.html

时间: 2024-10-12 09:33:42

多源多汇费用流——poj2516的相关文章

poj 1459 多源多汇点最大流

Sample Input 2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20 7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7 (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5 (0)5 (1)2 (3)2 (4)1 (5)4 7个点包括电站和用户,2个电站,3个用户,13条边,输入13条边,输入2个电站,输入3个用户 Sample Output 15 6 增加一个源点一个汇点

Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考

本期内容 : 数据接收架构设计模式 数据接收源码彻底研究 一.Spark Streaming数据接收设计模式   Spark Streaming接收数据也相似MVC架构: 1. Mode相当于Receiver存储数据,C级别的,Receiver是个抽象因为他有好多的Receiver 2. ReceiverSupervisor 是控制器,因为Receiver启动是靠ReceiverSuperior启动的,及接收到的数据交给ReceiverSuperior存储数据的 3. Driver会获得源数据,

.26-浅析webpack源码之事件流make(1)

compilation事件流中,依然只是针对细节步骤做事件流注入,代码流程如图: // apply => this-compilation // apply => compilation // return compialtion const compilation = this.newCompilation(params); this.applyPluginsParallel("make", compilation, err => { // callback...

第10课:Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考

上一课我们讲解了Receiver启动的流程.Receiver是通过ReceiverSupervisor的start方法启动的: /** Start the supervisor */ def start() {   onStart()   startReceiver() } 首先会调用ReceiverSupervisor的onStart()方法, override protected def onStart() {   registeredBlockGenerators.foreach { _.

(版本定制)第10课:Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考

本期内容: 1.数据接收架构设计模式 2.数据接收源码彻底研究 1.Receiver接受数据的过程类似于MVC模式: Receiver,ReceiverSupervisor和Driver的关系相当于Model,Control,View,也就是MVC. Model就是Receiver,存储数据Control,就是ReceiverSupervisor,Driver是获得元数据,也就是View. 2.数据的位置信息会被封装到RDD里面. 3.Receiver接受数据,交给ReceiverSupervi

[源码]ObjectIOStream 对象流 ByteArrayIOStream 数组流 内存流 ZipOutputStream 压缩流

1.对象流 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputS

Spark发行版笔记10:Spark Streaming源码解读之流数据不断接收和全生命周期彻底研究和思考

本节的主要内容: 一.数据接受架构和设计模式 二.接受数据的源码解读 Spark Streaming不断持续的接收数据,具有Receiver的Spark 应用程序的考虑. Receiver和Driver在不同进程,Receiver接收数据后要不断给Deriver汇报. 因为Driver负责调度,Receiver接收的数据如果不汇报给Deriver,Deriver调度时不会把接收的数据计算入调度系统中(如:数据ID,Block分片). 思考Spark Streaming接收数据: 不断有循环器接收

poj 1459 Power Network, 最大流,多源多汇

点击打开链接 多源多汇最大流,虚拟一个源点s'和一个汇点t',原来的源点.汇点向它们连边. #include<cstdiO> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int maxn = 500 + 5; const int INF = 100

有上下界的、有多组源汇的、网络流、费用流问题

先默认读者有基础的网络流以及费用流的知识前置 1.有上下界无源点汇点的可行流问题: 在本文中指: 原图中没有任何一个点可以凭空产生流量,亦没有任何一个点可以凭空消灭流量: 存在边既有流量上界又有流量下界: 求每条边流量的一组可行解: 满足每个点的入流量等于出流量: 由题意可见本题的图中有环,于是此类问题也被称作循环流: 这里给出的解法是将本题转换为一道普通的有上界最大流问题: 修改本题原图中每条边的流量下界为0,上界为原上界-原下界: 视为该边现在已经拥有了等同于该边流量下界的基础流量了, 然而