最小树形图模板
RT,模板题源自洛谷
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N1 105 5 #define M1 10050 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 9 template <typename _T> void read(_T &ret) 10 { 11 ret=0; _T fh=1; char c=getchar(); 12 while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); } 13 while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); } 14 ret=ret*fh; 15 } 16 17 struct Edge{ 18 int u[M1],v[M1],w[M1],cte; 19 void ae(int U,int V,int W) 20 { cte++; u[cte]=U; v[cte]=V; w[cte]=W; } 21 }e; 22 23 int n,m,root; 24 int ine[N1],pre[N1],vis[N1],id[N1]; 25 26 int zhuliu() 27 { 28 int i,j,x,v,w,cnt,ans=0; 29 while(1){ 30 31 memset(ine,0x3f,sizeof(ine)); 32 for(j=1;j<=m;j++) 33 { 34 x=e.u[j]; v=e.v[j]; 35 if(x!=v && ine[v]>e.w[j]) 36 ine[v]=e.w[j], pre[v]=x; 37 } 38 for(i=1;i<=n;i++) if(i!=root && ine[i]==inf) 39 return -1; 40 memset(vis,0,sizeof(vis)); 41 memset(id,0,sizeof(id)); 42 cnt=0; 43 for(i=1;i<=n;i++) 44 { 45 if(i==root) continue; 46 ans+=ine[i]; 47 x=i; 48 while(vis[x]!=i && !id[x] && x!=root) 49 { 50 vis[x]=i; x=pre[x]; 51 } 52 if(!id[x] && x!=root) 53 { 54 id[x]=++cnt; 55 for(v=pre[x];v!=x;v=pre[v]) id[v]=cnt; 56 } 57 } 58 if(!cnt) break; 59 for(i=1;i<=n;i++) if(!id[i]) 60 id[i]=++cnt; 61 for(i=1;i<=m;i++) 62 { 63 if(id[e.u[i]]!=id[e.v[i]]) e.w[i]-=ine[e.v[i]]; 64 e.u[i]=id[e.u[i]]; e.v[i]=id[e.v[i]]; 65 } 66 n=cnt; 67 root=id[root]; 68 69 } 70 return ans; 71 } 72 73 int main() 74 { 75 int i,j,x,y,w,ans; 76 scanf("%d%d%d",&n,&m,&root); 77 for(i=1;i<=m;i++) read(x), read(y), read(w), e.ae(x,y,w); 78 ans=zhuliu(); 79 printf("%d\n",ans); 80 return 0; 81 }