洛谷 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 
#include 
#include 
#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 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

你可能感兴趣的:(网络流)