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 }