P3376 【模板】网络最大流 dinic详解

dinic的核心在于分层和多路增广。
分层的意思是,对于图用bfs搜出每一层,避免出现dfs深度过深的情况。
多路增广,利用的是dfs的回溯性质,这样就可以在一个点增广出它的所有流量。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;

const int maxn=200100;
const int INF=0x3f3f3f3f;

int head[maxn];
int val[maxn];
int next[maxn];
int to[maxn];
int deep[maxn];
int cnt=1,n,m,s,t;

void addEdge(int u,int v,int w)
{
	to[++cnt]=v;
	val[cnt]=w;
	next[cnt]=head[u];
	head[u]=cnt;
}

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

int dfs(int u,int in)
{
	if (u==t) {
		return in;
	}
	int out=0;
	for (int i=head[u];i&&in;i=next[i]) {
		int v=to[i];
		if (val[i]&&deep[v]==deep[u]+1) {
			int res=dfs(v,min(val[i],in));
			val[i]-=res;
			val[i^1]+=res;
			in-=res;
			out+=res;
		}
	}
	if (out==0) {
		deep[u]=0;
	}
	return out;
}

int dinic()
{
	int ans=0;
	while (bfs()) {
		ans+=dfs(s,INF);
	}
	return ans;
}

int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	while (m--) {
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		addEdge(u,v,w);
		addEdge(v,u,0);
	}
	printf("%d\n",dinic());
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值