POJ-2377 Bad Cowtractors---最大生成树

时间:2022-09-08 20:53:56

题目链接:

https://vjudge.net/problem/POJ-2377

题目大意:

给一个图,求最大生成树权值,如果不连通输出-1

思路:

kruskal算法变形,sort按边从大到小排序,就可以了,或者用一个maxn-w[u][v]作为<u, v>边的权值,直接用原来的kruskal算法求出权值,然后用maxn*(n-1)-sum就为最大生成树权值

 1 #include<iostream>
 2 #include<vector>
 3 #include<queue>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdio>
 7 #include<set>
 8 #include<map>
 9 #include<cmath>
10 using namespace std;
11 typedef pair<int, int> Pair;
12 typedef long long ll;
13 const int INF = 0x3f3f3f3f;
14 int T, n, m;
15 const int maxn = 2e4 + 10;
16 struct edge
17 {
18     int v, u, w;
19     bool operator < (const edge a)const
20     {
21         return w > a.w;
22     }
23 };
24 edge e[maxn];
25 int pa[maxn];
26 int Find(int x)
27 {
28     return x == pa[x] ? x : pa[x] = Find(pa[x]);//路径压缩
29 }
30 void kruskal()
31 {
32     for(int i = 1; i <= n; i++)pa[i] = i;
33     sort(e, e + m);
34     ll ans = 0;
35     for(int i = 0; i < m; i++)
36     {
37         ll v = e[i].v, u = e[i].u, w = e[i].w;
38         ll x = Find(v), y = Find(u);
39         if(x != y)
40         {
41             pa[x] = y;
42             ans += w;
43         }
44     }
45     int tot = 0;
46     for(int i = 1; i <= n; i++)//判断是否联通,是否只有一个父节点是自己的点
47     {
48         if(pa[i] == i)tot++;
49     }
50     if(tot > 1)cout<<"-1"<<endl;
51     else cout<<ans<<endl;
52 }
53 int main()
54 {
55     cin >> n >> m;
56     for(int i = 0; i < m; i++)cin >> e[i].v >> e[i].u >> e[i].w;
57     kruskal();
58 }
 1 #include<iostream>
 2 #include<vector>
 3 #include<queue>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdio>
 7 #include<set>
 8 #include<map>
 9 #include<cmath>
10 using namespace std;
11 typedef pair<int, int> Pair;
12 typedef long long ll;
13 const int INF = 0x3f3f3f3f;
14 int T, n, m;
15 const int maxn = 2e4 + 10;
16 struct edge
17 {
18     int v, u, w;
19     bool operator < (const edge a)const
20     {
21         return w < a.w;
22     }
23 };
24 edge e[maxn];
25 int pa[maxn];
26 int Find(int x)
27 {
28     return x == pa[x] ? x : pa[x] = Find(pa[x]);//路径压缩
29 }
30 void kruskal()
31 {
32     for(int i = 1; i <= n; i++)pa[i] = i;
33     sort(e, e + m);
34     ll ans = 0;
35     for(int i = 0; i < m; i++)
36     {
37         ll v = e[i].v, u = e[i].u, w = e[i].w;
38         ll x = Find(v), y = Find(u);
39         if(x != y)
40         {
41             pa[x] = y;
42             ans += w;
43         }
44     }
45     int tot = 0;
46     for(int i = 1; i <= n; i++)//判断是否联通,是否只有一个父节点是自己的点
47     {
48         if(pa[i] == i)tot++;
49     }
50     ans = 100000LL * ((ll)n - 1) - ans;
51     if(tot > 1)cout<<"-1"<<endl;
52     else cout<<ans<<endl;
53 }
54 int main()
55 {
56     cin >> n >> m;
57     for(int i = 0; i < m; i++)
58     {
59         cin >> e[i].v >> e[i].u >> e[i].w;
60         e[i].w = 100000 - e[i].w;
61     }
62     kruskal();
63 }