ACM Contest and Blackout UVA - 10600

原题链接

考察:次小生成树

思路:

        模板题,这里我用的方法一,时间复杂度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 }

 

posted @ 2021-05-05 13:25  acmloser  阅读(40)  评论(0编辑  收藏  举报