zoukankan      html  css  js  c++  java
  • 【模板】网络最大流

    题意简述

    给出一个网络图,以及其源点和汇点,求出其网络最大流。

    代码

    #include <queue> 
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    int n, m, s, t, cnt = 1, u, v, w, ans;
    int h[10010], nxt[200010], va[200010], to[200010], dep[10010], lst[10010];
    inline void add_edge(const int& u, const int& v, const int& w)
    {
    	to[++cnt] = v;
    	va[cnt] = w;
    	nxt[cnt] = h[u];
    	h[u] = cnt;
    }
    bool bfs()
    {
    	std::queue <int> q;
    	memset(dep, 0, sizeof(dep));
    	q.push(t);
    	dep[t] = 1;
    	while (!q.empty())
    	{
    		int u = q.front();
    		q.pop();
    		for (register int i = h[u]; i; i = nxt[i])
    			if (va[i ^ 1] && !dep[to[i]])
    			{
    				dep[to[i]] = dep[u] + 1;
    				if (to[i] == s) return 1;
    				q.push(to[i]);
    			}
    	}
    	return 0;
    }
    int dfs(const int& u, int flow)
    {
    	int ss = 0;
    	if (u == t) return flow;
    	for (int& i = lst[u]; i; i = nxt[i])
    		if (dep[to[i]] == dep[u] - 1 && va[i])
    		{
    			int tmp = dfs(to[i], std::min(flow, va[i]));
    			va[i] -= tmp;
    			va[i ^ 1] += tmp;
    			flow -= tmp;
    			ss += tmp;
    			if (!flow) return ss;
    		}
    	if (!ss) dep[u] = 0;
    	return ss;
    }
    int main()
    {
    	scanf("%d%d%d%d", &n, &m, &s, &t);
    	for (register int i = 1; i <= m; ++i)
    	{
    		scanf("%d%d%d", &u, &v, &w);
    		add_edge(u, v, w);
    		add_edge(v, u, 0);
    	}
    	while (bfs())
    	{
    		for (register int i = 1; i <= n; ++i) lst[i] = h[i];
    		ans += dfs(s, 0x7fffffff);
    	}
    	printf("%d
    ", ans);
    }
    
  • 相关阅读:
    bzoj 2527: [Poi2011]Meteors 整体二分
    bzoj 2738 矩阵乘法
    bzoj 3110 K大数查询
    bzoj 3262 陌上花开
    cogs 577 蝗灾 CDQ分治
    bzoj 1101 zap
    bzoj 2005
    bzoj 3518 Dirichlet卷积
    bzoj 1257
    最优贸易 [NOIP 2009]
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/11191008.html
Copyright © 2011-2022 走看看