hdu-3371 Connect the Cities---kruskal

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3371

题目大意:

给n个城市,m条路,k组已知路,求最小费用联通所有城市;

解题思路:

kruskal求MST,这道题目有毒,很容易超时,改了一下并查集才过,而且同一个代码有时过又是超时

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 500 + 10;
 5 const int INF = 0x3f3f3f3f;
 6 int p[maxn];
 7 int tot;
 8 void init()
 9 {
10     for(int i = 0; i < maxn; i++)p[i] = i;
11 }
12 int f(int x)
13 {
14     return x == p[x] ? x : p[x] = f(p[x]);
15 }
16 void Union(int x, int y)
17 {
18     x = f(x);
19     y = f(y);
20     if(x != y)
21     {
22         p[x] = y;//这里改成p[y] = x;有时过,有时会超时
23         tot--;//不联通的数目减一
24     }
25 }
26 struct edge
27 {
28     int u, v, w;
29     bool operator < (const edge& a)
30     {
31         return w < a.w;
32     }
33 }a[maxn * maxn];
34 int main()
35 {
36     int T, n, m, k, t, x, y;
37     scanf("%d", &T);
38     while(T--)
39     {
40         init();
41         scanf("%d%d%d", &n, &m, &k);
42         tot = n - 1;//最开始,不连通块数目为n-1
43         for(int i = 1; i <= m; i++)
44         {
45             scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].w);
46         }
47         sort(a + 1, a + 1 + m);
48         while(k--)
49         {
50             scanf("%d%d", &t, &x);
51             t--;
52             while(t--)
53             {
54                 scanf("%d", &y);
55                 Union(x, y);
56             }
57         }
58         int ans = 0;/*
59         for(int i = 1; i <= n; i++)cout<<p[i]<<" ";
60         cout<<endl;*/
61         for(int i = 1; i <= m; i++)
62         {
63             int x = a[i].u;
64             int y = a[i].v;
65             x = f(x), y = f(y);
66             if(x != y)
67             {
68                 p[x] = y;
69                 tot--;//不连通数目减一
70                 ans += a[i].w;
71             }
72         }
73         if(tot == 0)//全部连通
74             printf("%d
", ans);
75         else
76             printf("-1
");
77     }
78     return 0;
79 }
原文地址:https://www.cnblogs.com/fzl194/p/8901553.html