【模板】最大流ISAP

存个板子

#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const

namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<20|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; 
	}
	
	inline int getint(){
		re char c;
		while(!isdigit(c=gc()));re int num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
}
using namespace IO;

struct edge{
	int to,cap,rev;
	edge(cs int &_to,cs int &_cap,cs int &_rev):to(_to),cap(_cap),rev(_rev){}
};

cs int N=1e4+4;
int n,m;
std::vector<edge> G[N];
typedef std::vector<edge>::iterator iter;
iter cur[N];

inline void addedge(int u,int v,int val){
	G[u].push_back(edge(v,val,G[v].size()));
	G[v].push_back(edge(u,0,G[u].size()-1));
}

int S,T;
int lev[N],gap[N];
inline void BFS(){
	memset(lev+1,-1,sizeof(int)*n);
	memset(gap,0,sizeof(int)*(n+2));
	lev[T]=gap[1]=1;
	std::queue<int,std::list<int> > q;
	q.push(T);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(iter re e=G[u].begin();e!=G[u].end();++e){
			int v=e->to;
			if(~lev[v])continue;
			q.push(v);
			++gap[lev[v]=lev[u]+1];
		}
	}
}

int dfs(int u,cs int &flow){
	if(u==T)return flow;
	int ans=0;
	for(iter &e=cur[u];e!=G[u].end();++e){
		if(e->cap&&lev[e->to]+1==lev[u]){
			int delta=dfs(e->to,std::min(flow-ans,e->cap));
			if(delta){
				e->cap-=delta;
				G[e->to][e->rev].cap+=delta;
				ans+=delta;
			}
			if(ans==flow)return ans;
		}
	}
	--gap[lev[u]];
	if(gap[lev[u]]==0)lev[S]=n+1;
	++lev[u];
	++gap[lev[u]];
	return ans;
}

int ISAP(){
	int mxflow=0;
	BFS();
	while(lev[S]<=n){
		for(int re i=1;i<=n;++i)cur[i]=G[i].begin();
		mxflow+=dfs(S,0x3f3f3f3f);
	}
	return mxflow;
}

signed main(){
//	freopen("lx.in","r",stdin);
	n=getint(),m=getint();
	S=getint(),T=getint();
	for(int re i=1;i<=m;++i){
		int u=getint(),v=getint(),val=getint();
		addedge(u,v,val);
	}
	std::cout<<ISAP()<<"\n";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值