Problem 1566 - C - Spanning Tree 动态最小生成树

                                Problem 1566 - C - Spanning Tree

给出一个联通图,然后每次加一条边,每次需要求最小生成树

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <string>
  7 #include <vector>
  8 #include <set>
  9 #include <map>
 10 #include <stack>
 11 #include <queue>
 12 #include <sstream>
 13 #include <iomanip>
 14 using namespace std;
 15 typedef long long LL;
 16 const int INF = 0x4fffffff;
 17 const double EXP = 1e-5;
 18 const int MS = 5005;
 19 const int SIZE = 100005;
 20 
 21 struct edge
 22 {
 23       int u,v,w;
 24       bool operator <(const edge &a)const
 25       {
 26             return w<a.w;
 27       }
 28 }edges[SIZE];
 29 
 30 int n,m,q,ans,cnt;
 31 
 32 int fa[MS];
 33 
 34 int find(int x)
 35 {
 36       int s;
 37       for(s=x;fa[s]>=0;s=fa[s]);
 38       while(s!=x)
 39       {
 40             int tmp=fa[x];
 41             fa[x]=s;
 42             x=tmp;
 43       }
 44       return s;
 45 }
 46 
 47 void merge(int u,int v)
 48 {
 49       int f1=find(u);
 50       int f2=find(v);
 51       int tmp=fa[f1]+fa[f2];
 52       if(fa[f1]>fa[f2])
 53       {
 54             fa[f1]=f2;
 55             fa[f2]=tmp;
 56       }
 57       else
 58       {
 59             fa[f2]=f1;
 60             fa[f1]=tmp;
 61       }
 62 }
 63 
 64 
 65 bool flag[MS];
 66 
 67 int MST()
 68 {
 69       int num=0,sum=0;
 70       sort(edges,edges+cnt);
 71       memset(fa,0xff,sizeof(fa));
 72       memset(flag,0,sizeof(flag));
 73       for(int i=0;i<cnt;i++)
 74       {
 75             int u=edges[i].u;
 76             int v=edges[i].v;
 77             int w=edges[i].w;
 78             if(find(u)!=find(v))
 79             {
 80                   merge(u,v);
 81                   flag[i]=1;
 82                   sum+=w;
 83                   num++;
 84             }
 85             if(num>=n-1)
 86                   break;
 87       }
 88       num=0;
 89       for(int i=0;i<cnt;i++)
 90             if(flag[i])
 91                   edges[num++]=edges[i];
 92       cnt=num;
 93       return sum;
 94 }
 95 
 96 int main()
 97 {
 98       int u,v,w;
 99       while(scanf("%d%d%d",&n,&m,&q)!=EOF)
100       {
101             cnt=0;
102             for(int i=0;i<m;i++)
103             {
104                   scanf("%d%d%d",&u,&v,&w);
105                   if(u==v)
106                         continue;
107                   edges[cnt].u=u;
108                   edges[cnt].v=v;
109                   edges[cnt++].w=w;
110             }
111             ans=MST();
112             for(int i=0;i<q;i++)
113             {
114                   scanf("%d%d%d",&u,&v,&w);
115                   if(u==v)
116                   {
117                         printf("%d\n",ans);
118                   }
119                   else
120                   {
121                         edges[cnt].u=u;
122                         edges[cnt].v=v;
123                         edges[cnt++].w=w;
124                         ans=MST();
125                         printf("%d\n",ans);
126                   }
127             }
128       }
129       return 0;
130 }

 

posted @ 2015-04-19 22:05  daydaycode  阅读(134)  评论(0编辑  收藏  举报