网络最大流模板

洛谷网络最大流模板题
不断找增广路,使得最大流变大

Ek 时间复杂度o(nm^2),可以处理10的三次方到10的四次方规模的网络;

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,s,t;
int head[20005];
int top=1;
struct node1{
	int v,val,next;
}node[200005]; 
struct node2{
	int v,edge;
}pre[200005];
void add(int v,int u,int val){
	node[++top].v=u;
	node[top].val=val;
	node[top].next=head[v];
	head[v]=top;
}
int vis[10005];
bool bfs(){
	queue<int> q;
	memset(pre,0,sizeof(pre));
	memset(vis,0,sizeof(vis));
	vis[s]=1;
	q.push(s);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=head[u];i;i=node[i].next){
			int d=node[i].v;
			if(!vis[d]&&node[i].val){
				pre[d].v=u;
				pre[d].edge=i;
				if(d==t) return 1;
				vis[d]=1;
				q.push(d);
			}
		}
	}
	return 0;
}
int suan(){
	int ans=0;
	while(bfs()){
		int minn=0x3f3f3f3f;
		for(int i=t;i!=s;i=pre[i].v)
			minn=min(minn,node[pre[i].edge].val);
		for(int i=t;i!=s;i=pre[i].v){
			node[pre[i].edge].val-=minn;
			node[pre[i].edge^1].val+=minn;
		}
		ans+=minn;
	}
	return ans;
}
int main(){
	scanf("%d%d%d%d",&n,&m,&s,&t);
	while(m--){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b,a,0);
	}
	printf("%d",suan());
	return 0;
}

dinic算法
时间复杂度o(nnm)可以处理10的四次方到10的五次方规模的网络

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf=1<<29,N=50010,M=300010;
int head[N],ver[N],edge[M],Next[N],d[N];
int n,m,s,t,tot,maxflow;
queue<int> q;
void add(int x,int y,int z){
	ver[++tot]=y; edge[tot]=z; Next[tot]=head[x],head[x]=tot;
	ver[++tot]=x; edge[tot]=0; Next[tot]=head[y],head[y]=tot;
}
bool bfs(){
	memset(d,0,sizeof(d));
	while(q.size())	q.pop();
	q.push(s);	d[s]=1;
	while(q.size()){
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=Next[i]){
			if(edge[i]&&!d[ver[i]]){
				q.push(ver[i]);
				d[ver[i]]=d[x]+1;
				if(ver[i]==t)	return 1;
			}
		}
	}
	return 0;
}
int dinic(int x,int flow){
	if(x==t)	return flow;
	int rest=flow,k;
	for(int i=head[x];i&&rest;i=Next[i])
		if(edge[i]&&d[ver[i]]==d[x]+1){
			k=dinic(ver[i],min(rest,edge[i]));
			if(!k)	d[ver[i]]=0;
			edge[i]-=k;
			edge[i^1]+=k;
			rest-=k;
		}
	return flow-rest;
}
int main(){
	scanf("%d%d",&n,&m);
	scanf("%d%d",&s,&t);
	tot=1;
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
	}
	int flow=0;
	while(bfs()){
		while(flow=dinic(s,inf))	maxflow+=flow;
	}
	printf("%d\n",maxflow);
	return 0;
}
发布了36 篇原创文章 · 获赞 11 · 访问量 667

猜你喜欢

转载自blog.csdn.net/weixin_43822647/article/details/102526748