版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/C20181220_xiang_m_y/article/details/82890745
学习一波朱刘算法:
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());
}