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

题目来源:

https://www.luogu.org/problemnew/show/P3376

题目描述:

 

题目描述

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

输入输出格式

输入格式:

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

接下来M行每行包含三个正整数ui、vi、wi,表示第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<=10,M<=25

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

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

样例说明:

题目中存在3条路径:

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

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

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

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

解题思路:

     模板题,我是用dinic来做,用邻接表存边,加了一点优化。。。。

代码:

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <iomanip>
#define ll long long
#define inf 1e9
const int maxn=10005;
using namespace std;
struct newt{
	int to,next;ll val;
}edge[30*maxn];
int head[maxn],cur[maxn],deep[maxn],n,m,S,T,cnt;
inline void addedge(int u,int v,ll w)
{
	edge[cnt].val=w;
	edge[cnt].to=v;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}

inline bool bfs()
{
	memset(deep,-1,sizeof(deep));
	queue<int>q;
	q.push(S);deep[S]=0;
	for(int i=1;i<=n;i++)cur[i]=head[i];
	while(!q.empty())
	{
		int now=q.front();q.pop();
		for(int i=head[now];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(deep[v]==-1&&edge[i].val>0)deep[v]=deep[now]+1,q.push(v);
		}
	}
	return deep[T]!=-1;
}
inline ll dfs(int u,ll op)
{
	if(u==T||op==0)return op;
	ll flow=0,used=0;
	for(int i=cur[u];i!=-1;i=edge[i].next){
		cur[u]=i;
		int v=edge[i].to;
		if(deep[v]==deep[u]+1&&edge[i].val>0){
			used=dfs(v,min(op,edge[i].val));
			if(!used)continue;
			flow+=used;op-=used;
			edge[i].val-=used;edge[i^1].val+=used;
			if(!op)break;
		}
	}
	if(!flow)deep[u]=-1;
	return flow;
}
int main()
{
	ios::sync_with_stdio(false);
	memset(head,-1,sizeof(head));
	cin>>n>>m>>S>>T;
	cnt=0;
	ll ans=0;
	for(int i=1;i<=m;i++)
	{
		int a,b;ll c;
		cin>>a>>b>>c;
		addedge(a,b,c);
		addedge(b,a,0);
	}
	while(bfs()){
		ans+=dfs(S,inf);
	}
	cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/81228966