洛谷 P3376 【模板】网络最大流

题目描述

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

输入输出格式

输入格式:

第一行包含四个正整数NMST,分别表示点的个数、有向边的个数、源点序号、汇点序号。

接下来M行每行包含三个正整数uiviwi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi

输出格式:

一行,包含一个正整数,即为该网络的最大流。

输入输出样例

输入样例#1 复制

4 5 4 3

4 2 30

4 3 20

2 3 20

2 1 30

1 3 40

输出样例#1 复制

50

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10M<=25

对于70%的数据:N<=200M<=1000

对于100%的数据:N<=10000M<=100000

样例说明:

题目中存在3条路径:

4-->2-->3,该路线可通过20的流量

4-->3,可通过20的流量

4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)

故流量总计20+20+10=50。输出50

题解:网络流EK算法模板。

#include <cstdio>
#include <queue>
#include <cstring>
#define N 100005
int n,m,s,t,cnt,ans,first[10005],pre[10005];
bool vis[10005];
struct bb{
	int fr,to,va,nxt;
}E[N*2];
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	if (ch=='-')
	{
		f=-1;
		ch=getchar();
	}
	while ((ch<'0')||(ch>'9')) ch=getchar();
	while ((ch>='0')&&(ch<='9'))
	{
		x=x*10+ch-48;
		ch=getchar();
	}
	return f*x;
}
inline void add(int x,int y,int z)
{
	E[cnt].fr=x;
	E[cnt].to=y;
	E[cnt].va=z;
	E[cnt].nxt=first[x];
	first[x]=cnt++;
	E[cnt].fr=y;
	E[cnt].to=x;
	E[cnt].va=0;
	E[cnt].nxt=first[y];
	first[y]=cnt++;
}
inline bool BFS()
{
	memset(vis,0,sizeof(vis));
	memset(pre,-1,sizeof(pre));
	queue<int> q;
	q.push(s);
	vis[s]=1;
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		for (int i=first[x];i!=-1;i=E[i].nxt)
		{
			int k=E[i].to;
			if ((E[i].va<=0)||vis[k]) continue;
			vis[k]=1;
			q.push(k);
			pre[k]=i;
			if (k==t) return 1;
		}
	}
	return 0;
}
inline void EK()
{
	while (BFS())
	{
		int i=pre[t],x=0x3f3f3f3f;
		while (i!=-1)
		{
			if (E[i].va<x) x=E[i].va;
			i=pre[E[i].fr];
		}
		i=pre[t];
		while (i!=-1)
		{
			E[i].va-=x;
			E[i^1].va+=x;
			i=pre[E[i].fr];
		}
		ans+=x;
	}
}
int main()
{
	n=read(),m=read(),s=read(),t=read();
	memset(first,-1,sizeof(first));
	for (int i=1;i<=m;i++)
	{
		int x=read(),y=read(),z=read();
		add(x,y,z);
	}
	EK();
	printf("%d\n",ans);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值