1. 程式人生 > >朱劉演算法模板

朱劉演算法模板

學習一波朱劉演算法:

https://blog.csdn.net/txl199106/article/details/62045479

附上蒟蒻自改程式碼,看起來比較簡潔。。。

#include<cstdio>
#include<cstring>
#define maxn 105
#define maxm 10005
int n,m,r,ans,INF=1e9;
int x[maxm],y[maxm],cst[maxm];
int in[maxn],vis[maxn],scc[maxn],pre[maxn];
int zhuliu()
{
	int ans=0,v,cnt;
	while(1)
	{
		for(int i=1;i<=n;i++) in[i]=INF,scc[i]=vis[i]=0;
		for(int i=1;i<=m;i++)
			if(x[i]!=y[i]&&cst[i]<in[y[i]])
				pre[y[i]]=x[i],in[y[i]]=cst[i];
		in[r]=0;
		for(int i=1;i<=n;i++) if(in[i]==INF) return -1;
		for(int i=1;i<=n;i++)
		{
			ans+=in[i];
			for(v=i;vis[v]^i&&!scc[v]&&v^r;v=pre[v]) vis[v]=i;
			if(v!=r&&!scc[v])
			{
				scc[v]=++cnt;
				for(v=pre[v];!scc[v];v=pre[v]) scc[v]=cnt;
			}
		}
		if(!cnt) break;
		for(int i=1;i<=n;i++) if(!scc[i]) scc[i]=++cnt;
		for(int i=1;i<=m;i++)
		{
			v=y[i];
			x[i]=scc[x[i]],y[i]=scc[y[i]];
			if(x[i]!=y[i]) cst[i]-=in[v];
		}
		n=cnt;cnt=0;
		r=scc[r];
	}
	return ans;
}
int main()
{
	scanf("%d%d%d",&n,&m,&r);
	for(int i=1;i<=m;i++)
		scanf("%d%d%d",&x[i],&y[i],&cst[i]);
	printf("%d\n",zhuliu());
}