最小树形图

朱刘

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> 
#define il inline
#define ri register
#define pc(i) putchar(i)
using namespace std;
const int M=1e4+2,inf=0x3f3f3f3f;
int n,o,m,rt,dis[102],pre[102],id[102],vis[102];
struct node{int u,v,w;}edge[M];
il int read()
{
	int as=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') as=(as<<3)+(as<<1)+(ch^48),ch=getchar();return as*f;
}
il void wt(int x){if(x<0)pc('-'),x=-x;if(x>9)wt(x/10);pc(x%10+48);}
il int zhuliu()
{
	int sum=0;
	while(true)
	{
		int ind=0,v=0;
		for(ri int i=1;i<=n;++i) dis[i]=inf,vis[i]=id[i]=0;
		for(ri int i=1;i<=m;++i)
			if(edge[i].u!=edge[i].v&&edge[i].w<dis[edge[i].v])
				dis[edge[i].v]=edge[i].w,pre[edge[i].v]=edge[i].u;
		for(ri int i=1;i<=n;++i) if(i!=rt&&dis[i]==inf) return -1;
		for(ri int i=1;i<=n;++i)
		{
			if(i==rt) continue;
			sum+=dis[i],v=i;
			while(vis[v]!=i&&!id[v]&&v!=rt) vis[v]=i,v=pre[v];
			if(!id[v]&&v!=rt) 
			{
				id[v]=++ind;
				for(ri int j=pre[v];j!=v;j=pre[j]) id[j]=ind;//i
			}
		}
		if(!ind) break;
		for(ri int i=1;i<=n;++i) if(!id[i]) id[i]=++ind;//==
		for(ri int i=1,tmp;i<=m;++i)
		{
			tmp=edge[i].v,edge[i].u=id[edge[i].u],edge[i].v=id[edge[i].v];
			if(edge[i].u!=edge[i].v) edge[i].w-=dis[tmp];//id
		}
		rt=id[rt],n=ind;
	}
	return sum;
}
int main()
{
	n=read(),m=read(),rt=read();
	for(ri int i=1;i<=m;++i) 
		edge[i].u=read(),edge[i].v=read(),edge[i].w=read();
	wt(zhuliu());
	return 0;
}

  

posted @ 2022-10-15 19:16  Bertidurlah  阅读(26)  评论(1)    收藏  举报