考察:次小生成树
思路:
模板题,这里我用的方法一,时间复杂度O(N*M+Mlog2m)
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 using namespace std; 6 const int N = 110,M = 105*105; 7 int n,m,h[N],p[N]; 8 vector<int> v; 9 struct Road{ 10 int a,b,w; 11 bool vis; 12 bool operator<(Road x){ 13 return this->w<x.w; 14 } 15 }road[M]; 16 int findf(int x) 17 { 18 if(p[x]!=x) p[x] = findf(p[x]); 19 return p[x]; 20 } 21 int main() 22 { 23 int T; 24 scanf("%d",&T); 25 while(T--) 26 { 27 scanf("%d%d",&n,&m); 28 v.clear(); 29 int ans_1 = 0,ans_2 = 0x3f3f3f3f; 30 for(int i=1;i<=n;i++) p[i] = i; 31 for(int i=1;i<=m;i++) 32 { 33 int a,b,c; scanf("%d%d%d",&a,&b,&c); 34 road[i] = {a,b,c,0}; 35 } 36 sort(road+1,road+m+1); 37 for(int i=1;i<=m;i++) 38 { 39 int pa = findf(road[i].a),pb = findf(road[i].b); 40 if(pa==pb) continue; 41 v.push_back(i); 42 p[pa] = pb; 43 ans_1+=road[i].w; 44 } 45 for(int i=0;i<v.size();i++) 46 { 47 int j = v[i]; 48 road[j].vis = 1; 49 int sum = 0,cnt = 0; 50 for(int k=1;k<=n;k++) p[k] = k; 51 for(int k=1;k<=m;k++) 52 { 53 if(road[k].vis) continue; 54 int pa = findf(road[k].a),pb = findf(road[k].b); 55 if(pa==pb) continue; 56 sum+=road[k].w; 57 p[pa] = pb; 58 cnt++; 59 } 60 if(cnt==n-1) ans_2 = min(ans_2,sum); 61 road[j].vis = 0; 62 } 63 printf("%d %d\n",ans_1,ans_2); 64 } 65 return 0; 66 }
ACM Contest and Blackout UVA - 10600
原文:https://www.cnblogs.com/newblg/p/14731540.html