最小树形图模板

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 }

 

posted @ 2019-04-05 11:04  guapisolo  阅读(207)  评论(0编辑  收藏  举报