Dinic bzoj1084草地排水

多路增廣+當前弧優化

#include <bits/stdc++.h>
#define N 1000010
#define M 8000010
#define INF INT_MAX
using namespace std;
int n,m,s,t,fir[N],nxt[M],to[M],res[M],tot(1),dis[N],q[N],ans,cur[N];

inline int read(){
	int s=0; char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) s=s*10+c-'0',c=getchar();
	return s;
}

inline void add(int u,int v,int w){
	to[++tot]=v; nxt[tot]=fir[u]; fir[u]=tot; res[tot]=w;
	to[++tot]=u; nxt[tot]=fir[v]; fir[v]=tot; res[tot]=0;
}

int dfs(int x,int limit){
	if (x==t || !limit)
		return limit;
	int i,flow,cnt(0);
	for (i=cur[x];i;i=nxt[i])
		if (dis[to[i]]==dis[x]+1 && res[i]){
		flow=dfs(to[i],min(limit-cnt,res[i]));
		cnt+=flow;
		res[i]-=flow,res[i^1]+=flow;
		if (cnt==limit)
			break;
	}
	if (cnt<limit)
		dis[x]=-1;
	cur[x]=i;
	return cnt;
}

bool bfs(int s){
	for (int i=1;i<=n;i++)
		dis[i]=-1; 
	int head(1),tail(1);
	for (dis[s]=1,q[1]=s;head<=tail;head++){
		int x=q[head];
		for (int i=fir[x];i;i=nxt[i])
			if (!~dis[to[i]] && res[i]){
				dis[to[i]]=dis[x]+1;
				if (to[i]==t)
					return 1;
				q[++tail]=to[i];
			}
	}
	return 0;
}

void dinic(){
	ans=0;
	while (bfs(s)){
		for (int i=1;i<=n;i++)
			cur[i]=fir[i];
		ans+=dfs(s,INF);
	}
}

int main(){
	n=read(),m=read(),s=read(),t=read();
	int u,v,w;
	for (int i=1;i<=m;i++){
		u=read(),v=read(),w=read();
		add(u,v,w);
	}
	dinic();
	printf("%d\n",ans);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章