【图论】网络流一些模板

AcWing.2188 无源汇上下界可行流

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int N=210;
const int M=(10200+N)*2;
int n,m,S,T;
int head[N],d[N],cur[N],tot;
struct E{
	int to,next,cap,low;
}edge[M];
void add(int u,int v,int c,int d){
	edge[tot].to=v;
	edge[tot].next=head[u];
	edge[tot].cap=d-c;
	edge[tot].low=c;
	head[u]=tot++;
	edge[tot].to=u;
	edge[tot].next=head[v];
	edge[tot].cap=0;
	head[v]=tot++;	
}
bool bfs(){
	memset(d,-1,sizeof(d));	
	queue<int> q;
	q.push(S);d[S]=0;cur[S]=head[S];
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(d[v]==-1&&edge[i].cap){
				d[v]=d[u]+1;
				cur[v]=head[v];
				if(v==T) return true;
				q.push(v);
			}			
		}
	}
	return false;
}
int dfs(int u,int limit){
	if(u==T) return limit;
	int flow=0;
	for(int i=cur[u];i!=-1&&flow<limit;i=edge[i].next){
		cur[u]=i;
		int v=edge[i].to;
		if(d[v]==d[u]+1&&edge[i].cap){
			int delta=dfs(v,min(edge[i].cap,limit-flow));
			if(!delta) d[v]=-1;
			edge[i].cap-=delta;
			edge[i^1].cap+=delta;
			flow+=delta;
		}
	}
	return flow;
}
int dinic(){
	int maxFlow=0,delta;
	while(bfs()){
		while(delta=dfs(S,INF)){
			maxFlow+=delta;
		}
	}
	return maxFlow;  	
}
int A[N];
int main(){
	cin>>n>>m;mem(head,-1);
	S=0,T=n+1;
	rep(i,1,m){
		int a,b,c,d;
		cin>>a>>b>>c>>d;
		add(a,b,c,d);
		A[a]-=c;A[b]+=c;	
	}
	int num=0;
	rep(i,1,n){
		if(A[i]>0) add(S,i,0,A[i]),num+=A[i];
		else if(A[i]<0) add(i,T,0,-A[i]);
	}
	if(dinic()!=num) puts("NO");
	else{
		puts("YES");
		for(int i=0;i<m*2;i+=2){
			cout<<edge[i^1].cap+edge[i].low<<endl;
		}
	}
	return 0;
}

AcWing.2189有源汇上下界最大流模板

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int N=210;
const int M=(N+10000)*2;
int n,m,S,T;
int head[N],d[N],cur[N],A[N],tot;
struct E{
	int to,next,cap;
}edge[M];
void add(int u,int v,int w){
	edge[tot].to=v;
	edge[tot].next=head[u];
	edge[tot].cap=w;
	head[u]=tot++;
	edge[tot].to=u;
	edge[tot].next=head[v];
	edge[tot].cap=0;
	head[v]=tot++;	
}
bool bfs(){
	memset(d,-1,sizeof(d));	
	queue<int> q;
	q.push(S);d[S]=0;cur[S]=head[S];
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(d[v]==-1&&edge[i].cap){
				d[v]=d[u]+1;
				cur[v]=head[v];
				if(v==T) return true;
				q.push(v);
			}			
		}
	}
	return false;
}
int dfs(int u,int limit){
	if(u==T) return limit;
	int flow=0;
	for(int i=cur[u];i!=-1&&flow<limit;i=edge[i].next){
		cur[u]=i;
		int v=edge[i].to;
		if(d[v]==d[u]+1&&edge[i].cap){
			int delta=dfs(v,min(edge[i].cap,limit-flow));
			if(!delta) d[v]=-1;
			edge[i].cap-=delta;
			edge[i^1].cap+=delta;
			flow+=delta;
		}
	}
	return flow;
}
int dinic(){
	int maxFlow=0,delta;
	while(bfs()){
		while(delta=dfs(S,INF)){
			maxFlow+=delta;
		}
	}
	return maxFlow;  	
}
int main(){
	int s,t;
	cin>>n>>m>>s>>t;
	S=0,T=n+1;
	memset(head,-1,sizeof(head));
	while(m--){
		int a,b,c,d;cin>>a>>b>>c>>d;
		add(a,b,d-c);
		A[a]-=c;A[b]+=c;
	}
	int num=0;
	rep(i,1,n){
		if(A[i]>0) {add(S,i,A[i]),num+=A[i];}
		else if(A[i]<0) {add(i,T,-A[i]);}
	}
	add(t,s,INF);
	if(dinic()<num) puts("No Solution");
	else{
		int res=edge[tot-1].cap;
		S=s,T=t;
		edge[tot-1].cap=edge[tot-2].cap=0;
		cout<<res+dinic()<<endl;
	}
}

AcWing.2190有源汇上下界最小流

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=2147483647;
const int mod=1e9+7;
const int N=50010;
const int M=(N+125003)*2;
int n,m,S,T;
int head[N],d[N],cur[N],A[N],tot;
struct E{
	int to,next,cap;
}edge[M];
void add(int u,int v,int w){
	edge[tot].to=v;
	edge[tot].next=head[u];
	edge[tot].cap=w;
	head[u]=tot++;
	edge[tot].to=u;
	edge[tot].next=head[v];
	edge[tot].cap=0;
	head[v]=tot++;	
}
bool bfs(){
	memset(d,-1,sizeof(d));	
	queue<int> q;
	q.push(S);d[S]=0;cur[S]=head[S];
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(d[v]==-1&&edge[i].cap){
				d[v]=d[u]+1;
				cur[v]=head[v];
				if(v==T) return true;
				q.push(v);
			}			
		}
	}
	return false;
}
int dfs(int u,int limit){
	if(u==T) return limit;
	int flow=0;
	for(int i=cur[u];i!=-1&&flow<limit;i=edge[i].next){
		cur[u]=i;
		int v=edge[i].to;
		if(d[v]==d[u]+1&&edge[i].cap){
			int delta=dfs(v,min(edge[i].cap,limit-flow));
			if(!delta) d[v]=-1;
			edge[i].cap-=delta;
			edge[i^1].cap+=delta;
			flow+=delta;
		}
	}
	return flow;
}
int dinic(){
	int maxFlow=0,delta;
	while(bfs()){
		while(delta=dfs(S,INF)){
			maxFlow+=delta;
		}
	}
	return maxFlow;  	
}
int main(){
	int s,t;
	cin>>n>>m>>s>>t;
	S=0,T=n+1;
	memset(head,-1,sizeof(head));
	while(m--){
		int a,b,c,d;cin>>a>>b>>c>>d;
		add(a,b,d-c);
		A[a]-=c;A[b]+=c;
	}
	int num=0;
	rep(i,1,n){
		if(A[i]>0) {add(S,i,A[i]),num+=A[i];}
		else if(A[i]<0) {add(i,T,-A[i]);}
	}
	add(t,s,INF);
	if(dinic()<num) puts("No Solution");
	else{
		int res=edge[tot-1].cap;
		S=t,T=s;
		edge[tot-1].cap=edge[tot-2].cap=0;
		cout<<res-dinic()<<endl;
	}
}

AcWing.2234多源汇最大流

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=2147483647;
const int mod=1e9+7;
const int N=10010;
const int M=(N+100005)*2;
int n,m,S,T;
int head[N],d[N],cur[N],A[N],tot;
struct E{
	int to,next,cap;
}edge[M];
void add(int u,int v,int w){
	edge[tot].to=v;
	edge[tot].next=head[u];
	edge[tot].cap=w;
	head[u]=tot++;
	edge[tot].to=u;
	edge[tot].next=head[v];
	edge[tot].cap=0;
	head[v]=tot++;	
}
bool bfs(){
	memset(d,-1,sizeof(d));	
	queue<int> q;
	q.push(S);d[S]=0;cur[S]=head[S];
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(d[v]==-1&&edge[i].cap){
				d[v]=d[u]+1;
				cur[v]=head[v];
				if(v==T) return true;
				q.push(v);
			}			
		}
	}
	return false;
}
int dfs(int u,int limit){
	if(u==T) return limit;
	int flow=0;
	for(int i=cur[u];i!=-1&&flow<limit;i=edge[i].next){
		cur[u]=i;
		int v=edge[i].to;
		if(d[v]==d[u]+1&&edge[i].cap){
			int delta=dfs(v,min(edge[i].cap,limit-flow));
			if(!delta) d[v]=-1;
			edge[i].cap-=delta;
			edge[i^1].cap+=delta;
			flow+=delta;
		}
	}
	return flow;
}
int dinic(){
	int maxFlow=0,delta;
	while(bfs()){
		while(delta=dfs(S,INF)){
			maxFlow+=delta;
		}
	}
	return maxFlow;  	
}
int main(){
	int sc,tc;
	cin>>n>>m>>sc>>tc;
	S=0,T=n+1;
	memset(head,-1,sizeof(head));
	while(sc--){
		int x;cin>>x;
		add(S,x,INF);
	}
	while(tc--){
		int x;cin>>x;
		add(x,T,INF);
	}
	while(m--){
		int a,b,c;cin>>a>>b>>c;
		add(a,b,c);
	}
	cout<<dinic()<<endl;
}

AcWing.2236 寻找关键边

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=2147483647;
const int mod=1e9+7;
const int N=600;
const int M=(N+10005)*2;
int n,m,S,T;
int head[N],d[N],cur[N],A[N],tot;
struct E{
	int to,next,cap;
}edge[M];
void add(int u,int v,int w){
	edge[tot].to=v;
	edge[tot].next=head[u];
	edge[tot].cap=w;
	head[u]=tot++;
	edge[tot].to=u;
	edge[tot].next=head[v];
	edge[tot].cap=0;
	head[v]=tot++;	
}
bool bfs(){
	memset(d,-1,sizeof(d));	
	queue<int> q;
	q.push(S);d[S]=0;cur[S]=head[S];
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(d[v]==-1&&edge[i].cap){
				d[v]=d[u]+1;
				cur[v]=head[v];
				if(v==T) return true;
				q.push(v);
			}			
		}
	}
	return false;
}
int dfs(int u,int limit){
	if(u==T) return limit;
	int flow=0;
	for(int i=cur[u];i!=-1&&flow<limit;i=edge[i].next){
		cur[u]=i;
		int v=edge[i].to;
		if(d[v]==d[u]+1&&edge[i].cap){
			int delta=dfs(v,min(edge[i].cap,limit-flow));
			if(!delta) d[v]=-1;
			edge[i].cap-=delta;
			edge[i^1].cap+=delta;
			flow+=delta;
		}
	}
	return flow;
}
int dinic(){
	int maxFlow=0,delta;
	while(bfs()){
		while(delta=dfs(S,INF)){
			maxFlow+=delta;
		}
	}
	return maxFlow;  	
}
bool vis_s[N],vis_t[N];
void dfss(int u,bool st[],int t){
	st[u]=true;
	for(int i=head[u];i!=-1;i=edge[i].next){
		int j=i^t,v=edge[i].to;
		if(edge[j].cap&&!st[v]){
			dfss(v,st,t);
		}
	}
}
int main(){
	cin>>n>>m;
	S=0,T=n-1;
	memset(head,-1,sizeof(head));
	for(int i=0;i<m;i++){
		int a,b,c;cin>>a>>b>>c;
		add(a,b,c);
	}
	dinic();
	dfss(S,vis_s,0);
	dfss(T,vis_t,1);
	int res=0;
	for(int i=0;i<m*2;i+=2){
		if(!edge[i].cap&&vis_s[edge[i^1].to]&&vis_t[edge[i].to]){
			res++;
		}
	}
	cout<<res<<endl;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值