• 网络流EK算法模板


    (EK)算法的思想就是每一次找一条增广路进行增广。

    注意几个点:

    • 存图时(head)数组要设为(-1)
    • 存图的代码是这样的:
    inline void add(int u, int v, int w)
    {
    	ver[tot] = v, fro[tot] = u, edge[tot] = w, nxt[tot] = head[u], head[u] = tot++;
    	ver[tot] = u, fro[tot] = v, edge[tot] = 0, nxt[tot] = head[v], head[v] = tot++;//注意最后才tot++,且需要建流量为0的反边
    }
    

    具体实现参考代码:

    #include <bits/stdc++.h>
    #define itn int
    #define gI gi
    
    using namespace std;
    
    inline int gi()
    {
    	int f = 1, x = 0; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar();
    	return f * x;
    }
    
    const int maxn = 100003;
    
    int n, m, s, t, tot, fro[maxn * 2], head[maxn], ver[maxn * 2], nxt[maxn * 2], edge[maxn * 2];
    int flow[maxn], pre[maxn], pos[maxn], ans;
    
    inline void add(int u, int v, int w)
    {
    	ver[tot] = v, fro[tot] = u, edge[tot] = w, nxt[tot] = head[u], head[u] = tot++;
    	ver[tot] = u, fro[tot] = v, edge[tot] = 0, nxt[tot] = head[v], head[v] = tot++;
    }
    
    queue <int> q;
    
    inline int Max_flow(int s, int t)
    {
    	memset(pos, -1, sizeof(pos));
    	memset(pre, -1, sizeof(pre));
    	while (!q.empty()) q.pop();
    	q.push(s);
    	flow[s] = 0x3f3f3f3f;
    	//以上为初始化
    	while (!q.empty())
    	{
    		int u = q.front(); q.pop();
    		if (u == t) return flow[u];//找到了一条增广路
    		for (int i = head[u]; i != -1; i = nxt[i])//遍历出边
    		{
    			int v = ver[i], w = edge[i];
    			if (pre[v] == -1 && w > 0)//下一个点还可以增广
    			{
    				pre[v] = u;//记录前驱
    				pos[v] = i;//记录当前边的编号
    				flow[v] = min(flow[u], w);//记录流量
    				q.push(v);//放入队列
    			}
    		}
    	}
    	return -1;
    }
    
    inline void EK(int s, int t)
    {
    	int ins = 0;
    	while ((ins = Max_flow(s, t)) != -1)//当前还存在增广路
    	{
    		int k = t;//向前推进
    		while (k != s)
    		{
    			edge[pos[k]] -= ins;//边的流量减去当前增广出的最大流量
    			edge[pos[k] ^ 1] += ins;//反边则加上最大流量
    			k = pre[k];//向前记录
    		}
    		ans += ins;//增加答案
    	}
    }
    
    int main()
    {
    	n = gi(), m = gi(), s = gi(), t = gi();
    	memset(head, -1, sizeof(head));//记得初始值设为-1
    	for (int i = 1; i <= m; i+=1)
    	{
    		int u = gi(), v = gi(), w = gi();
    		add(u, v, w);//建边
    	}
    	EK(s, t);//EK算法跑网络流
    	printf("%d
    ", ans);//输出答案
    	return 0;
    }
    
  • 相关阅读:
    字符串里输出字符c的所有位置
    python时间戳
    python之set()和issubset()方法
    python之判断键是否存在于字典中
    python之方法与函数的区别,及其传参
    接口测试之requests
    python之isinstance()函数
    MySQL创建表时,被``和''坑了很久
    游标位置self.cur.scroll(0, mode='absolute')
    python操作MySQL数据库
  • 原文地址:https://www.cnblogs.com/xsl19/p/maxflow-ek.html
Copyright © 2020-2023  润新知