[网络流]最大流模板

网络流最大流最小割

题目链接

就是一道点割最小割模板。

找了许久的模板,终于遇到了

先说边割

边割比较常见。

最大流

最大流等于最小割,我懒得证。

求最大流的思路就是每次尝试找一条从源点到汇点的通路,然后找到这条路上残余流量最小的流量,答案加上这个流量,这条通路上每条边的残余流量减去这个值,反向边加上这个值。

关于反向边,实际上是一个反悔机制。反向流多少,表示正向已经流了多少。也就是说,如果我们从反向边流了一些流量,就相当于从这条边退回了一部分流量。

点割

所谓点割,就是被割掉的不再是边,而是点。思路是将点转化成边。

如上题:将每个点拆成\(i\)和\(i+n\)两个点,中间连一条流量为\(1\)的边,将这条边割掉,就相当于割掉这个点。

详见代码。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
long long read(){
    long long x = 0; int f = 0; char c = getchar();
    while(c < '0' || c > '9') f |= c == '-', c = getchar();
    while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? -x:x;
}

const int INF = 2147483647;
int n, m, s, t;
struct szh{
    int nxt, to, w;
}a[4004];
int head[203],cnt=1;
void add(int x, int y, int w){
    a[++cnt].nxt = head[x], a[cnt].to = y, head[x] = cnt, a[cnt].w = w;
}

int dis[203];
bool bfs(){
    memset(dis, 0, sizeof dis);
    queue<int> q;
    q.push(s), dis[s] = 1;
    while(!q.empty()){
        int u = q.front();q.pop();
        for (int i = head[u], v; v = a[i].to, i; i = a[i].nxt)
            if(a[i].w && !dis[v]) q.push(v), dis[v] = dis[u] + 1;
    }
    return dis[t];
}

int fir[103];
int dfs(int u, int flow){
    if(u == t || !flow) return flow;
    int ans = 0;
    for (int &i = fir[u], v; v = a[i].to, i; i = a[i].nxt)
        //弧优化
        if(a[i].w && dis[v] == dis[u] + 1){
            int x = dfs(v, min(flow, a[i].w));
            a[i].w -= x, a[i^1].w += x, ans += x; //更新残余流量
            if(!(flow-=x)) break;
        }
    return ans;
}

void dinic(){
    int ans = 0;
    while(bfs()){
        for (int i = 1; i <= (n << 1); ++i) fir[i] = head[i];
        //为dfs中取址操作做铺垫
        ans += dfs(s,INF);
    }
    printf("%d", ans);
}

int main(){
    n = read(), m = read(), s = read(), t = read();
    s += n; //源点不能删掉
    for (int i = 1; i <= n; ++i) add(i, i + n, 1), add(i + n, i, 0);
    //拆点
    for (int i = 1; i <= m; ++i){
        int x = read(), y = read();
        add(x + n, y, INF), add(y, x + n, 0); //电脑之间不会断,所以连INF
        add(y + n, x, INF), add(x, y + n, 0);
    }
    dinic(); //模板
    return 0;
}

原文地址:https://www.cnblogs.com/kylinbalck/p/10590252.html

时间: 2024-08-08 20:50:18

[网络流]最大流模板的相关文章

网络流最大流模板(洛谷3376)——Dinic

小道消息,据说NOIP 2017 的六个题是三位(前?)国家队大神出的,所以难度很有可能贼高,并且可能出现网络流,所以慌慌张张地来打了个Dinic 模板,但愿汝佳所说“在大多数比赛中已经完全够用了”是对的. 1 #include<queue> 2 #include<vector> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib

P3376 网络流-最大流模板题(Dinic+当前弧优化)

(点击此处查看原题) Dinic算法 Dinic算法相对于EK算法,主要区别在于Dinic算法对图实现了分层,使得我们可以用一次bfs,一次dfs使得多条增广路得到增广 普通的Dinic算法已经可以处理绝大多数最大流(最小割)的题目了,但是总是有些题目会卡住普通的Dinic算法,此时我们就需要用到当前弧优化了 当前弧优化简述 不要小看当前弧优化,这个优化效果可是很明显的,就这个例题来说,我用普通的Dinic算法用时约1.7s,而使用了当前弧优化的Dinic算法后,只用了176ms,由此可以看出这

hdu 4289 Control(网络流 最大流+拆点)(模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1545    Accepted Submission(s): 677 Problem Description You, the head of Department o

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

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

网路流模板+总结

如此繁复多样的一类问题,就先从模板开始吧 1.最大流算法 模板题:https://www.luogu.org/problemnew/show/P3376 以下所有模板皆以上述问题为准 (1)FF算法(Ford-Fulkerson) 这便是最基础的一种增广路算法. 而所有增广路算法都使用了一种重要的技巧:对所有edge.cap>0的边构造反向边rev(e). 而在我个人看来,构造反向边的精妙之处就在于它使得两个看上去不相干的较难处理的操作化为了一个符合dfs基本法的操作,即所谓的"退流&qu

POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次只能向右和向下走,走到一个格子上加上格子的数,可以走k次.问最大的和是多少. 思路: 建图:每个格子掰成两个点,分别叫"出点","入点", 入点到出点间连一个容量1,费用为格子数的边,以及一个容量∞,费用0的边. 同时,一个格子的"出点"向它右.下的格子的"入点"连边,容量∞,费用0. 源点向(0,0)的入点连一个容量K的边,(N-1,N-1)的出点向汇点连一

POJ训练计划2516_Minimum Cost(网络流/费用流)

解题报告 题意: 有n个商店,m个提供商,k种商品</span> n*k的矩阵,表示每个商店需要每个商品的数目: m*k矩阵,表示每个提供商拥有每个商品的个数 然后对于每个物品k,都有n*m的矩阵 i行j列表示 从j提供商向i商店运送一个k商品的代价是多少 判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用 思路: 建图的题,不能直接把所有信息建成图,因为n和m跟k都有关系,如果那样子建图的话,就要把k种拆成m类,每个仓库连向该仓库的第k种,然后再和n连线,有费用, 不过这样

POJ 1459 Power Network(网络流 最大流 多起点,多汇点)

Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 22987   Accepted: 12039 Description A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied

POJ 1273 Drainage Ditches(网络流 最大流)

Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 55893   Accepted: 21449 Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by