最小费用可行流

https://www.cnblogs.com/guapisolo/p/10348428.html  原博

// ccf 201812-5 管道清洁: 最小费用可行流

#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
const int maxn = 233;
const int inf = 0x3f3f3f3f;
struct node{
    int u,v,f,w,nxt;
    node(){};
    node(int a,int b,int c,int d,int e):u(a),v(b),f(c),w(d),nxt(e){}
}e[maxn*maxn];
int cnt = 0;
int head[maxn];
void add(int u,int v,int f,int w){
    e[cnt] = node(u,v,f,w,head[u]);
    head[u] = cnt++;
    e[cnt] = node(v,u,0,-w,head[v]);
    head[v] = cnt++;
}
int st,ed,E,ex;
int n,m;
int du[maxn];
int sum;
int num = 0;
void init(){
    scanf("%d%d",&n,&m);
    st = 0;ed = n + 1;
    ex = n + 2;
    cnt = 0;
    sum = 0;
    num = 0;
    memset(head,-1,ex<<2);
    memset(du,0,ex<<2);
    while(m--){
        int u,v;char c[2];
        scanf("%d%d%s",&u,&v,c);
        if(c[0] == ‘A‘){
            add(u,v,inf,E);
            du[u]--;
            du[v]++;
            num+=E;
        }
        else if(c[0] == ‘B‘){
            du[u]--;
            du[v]++;
            num+=E;
        }
        else if(c[0] == ‘C‘){
            add(u,v,inf,E);
        }
        else add(u,v,1,E);
    }
    for(int i = 1;i <= n;++i){
        if(du[i] > 0){
            sum += du[i];
            add(st,i,du[i],0);
        }
        else if(du[i] < 0){
            add(i,ed,-du[i],0);
        }
    }
}
int pre[maxn];
int flow[maxn];
int inq[maxn];
int dis[maxn];
int spfa(){
    memset(pre,-1,ex<<2);
    memset(inq,0,ex<<2);
    memset(dis,0x3f,ex<<2);
    queue<int> q;q.push(st);
    flow[st] = inf;inq[st] = 1;
    dis[st] = 0;
    while(q.size()){
        int u = q.front();q.pop();
        inq[u] = 0;
        for(int i = head[u];i != -1; i = e[i].nxt){
            int v = e[i].v;
            if(e[i].f && dis[v] > dis[u] + e[i].w){
                dis[v] = dis[u] + e[i].w;
                pre[v] = i;
                flow[v] = min(flow[u],e[i].f);
                if(!inq[v]) inq[v] = 1,q.push(v);
            }
        }
    }
    if(pre[ed] == -1) return -1;
    return flow[ed];
}
int mfmv(){
    int fw = 0;
    int ans = 0;
    int d;
    while((d = spfa())!=-1){
        fw += d;
        ans += dis[ed]*d;
        int v = ed;
        while(v!=st){
            e[pre[v]].f -= d;
            e[pre[v]^1].f += d;
            v = e[pre[v]].u;
        }
    }
    if(fw!=sum) return -1;
    return ans + num;
}
void sol(){
    int ans = mfmv();
    printf("%d\n",ans);
}
int main(){
    int T;cin>>T;cin>>E>>E;
    while(T--){
        init();sol();
    }
} 

原文地址:https://www.cnblogs.com/shiliuxinya/p/12203353.html

时间: 2024-11-02 09:19:53

最小费用可行流的相关文章

【CF708D】Incorrect Flow 最小费用可行流

[CF708D]Incorrect Flow 题意:给你一个点数为n,边数为m的流网络,每条边有一个容量c和流量f,这个网络可能是不合法的.你可以花费1的代价使c或f减少或增加1,可以修改无限次.你不需要使流量最大,你只需要花费最少的代价把原图改造成一个合法的网络. $n,m\le 100,c,f\le 10^6$ 题解:我们用有上下界的费用流来解决这个问题. 对于一条边a->b,如果c>f,则我们从a到b连一条下界和上界都是f,费用为0的边:因为可以减少流量,所以连一条从b到a,容量为f,费

[HDOJ6118] 度度熊的交易计划(最小费用可行流)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6118 这个建图炒鸡简单,中间的图去掉重边后丢进去就行. 建图的时候费用实际上是价值,所以正的费用就不用跑了,相当于求费用可行流. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12 ┛┗┛┗┛┃ 1

CCF(管道清洁):最小费用最大流

管道清洁 201812-5 需要清洁的管道下界为1, 不需要清洁的管道下界为0, 可重复经过的管道上界为正无穷, 不可重复经过的管道上界为1. 这属于无源无汇的有容量下界的最小费用可行流.解决的方法就是首先增加一个源点和一个汇点,然后对每一条有下限的弧进行改造,改成容量下限为0,上限为c-b的一条弧,再增加两条分别从x点指向源点的上限为b的弧,以及从源点指向y点的上限为b的弧. 最后,只需要求改造后的s-t的最小费用流就行了.但是当且仅当附加弧满载时候原网络有可行流. #include<iost

HDU 6118 度度熊的交易计划 最大费用可行流

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6118 题意:中文题 分析: 最小费用最大流,首先建立源点 s ,与超级汇点 t .因为生产一个商品需要花费 a[i] 元,且上限为 b[i] ,所以我们从 s 向这些点之间连一条容量为 b[i] ,费用为 a[i] 的边.同样的道理,出售一个商品可以赚到 c[i] 元,最多出售 d[i] 个,于是我们从这些点向 t 连一条容量为 d[i] ,费用为 -c[i] 的边.最后所有的公路也是花费,从 u

zoj 3885 The Exchange of Items 【最小费用最大流】

The Exchange of Items Time Limit: 2 Seconds      Memory Limit: 65536 KB Bob lives in an ancient village, where transactions are done by one item exchange with another. Bob is very clever and he knows what items will become more valuable later on. So,

最小费用最大流粗解 poj2516

最小费用最大流,一般解法如下: 在流量基础上,每条边还有权费用,即单位流量下的所需费用.在最大流量下,求最小费用.解法:在最大流算法基础上,每次按可行流增广改为每次用spfa按最小费用(用单位费用)增广,每次按每条边一单位费用求到达终点的最小费用(最短路),那么每次找到"最短路"(只是一条路,不是多条(dinic每次可以增广多条)),之后按这条路最大 可能流量增广(取这条路上残量最小的),直到无法增广为止.(实现细节点代码备注). 该题题意:m个供应地向n个商店供应k种物品,对于每种物

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直

【BZOJ3876】【Ahoi2014】支线剧情 有下界的最小费用最大流

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43025375"); } [BZOJ2324]营救皮卡丘 这道题也是一道有下界的最小费用最大流. 我的题解地址:http://blog.csdn.net/vmurder/article/details/41378979 这道题其实就是模板题. 我的处理

POJ 3686.The Windy&#39;s 最小费用最大流

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5477   Accepted: 2285 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The ma