SGU---462 Electrician 最大生成树

题目链接:

https://cn.vjudge.net/problem/SGU-462

题目大意:

有N条电线需要接入电网,第i条电线计划连接ai和bi两个地点,电线有两个属性:ri(电线稳定度)和ci(电线价值)。电线需要依次接入,如果形成了环,那么环上稳定度最低的电线就会被烧毁。你需要确定一个接入电线的顺序,使得电线总价值最大。

解题思路:

由于形成环,环上的最低稳定度的电线会被烧毁,所以最终的结果一定没有环,也就是一棵以r为关键字的最大生成树(因为最小的r在环上会被烧断,完好无损的就是最大的r),要使得价值最大,那么相同的r就按照价值大的排在前面,排好序求出最大生成树那就是最大价值。

至于连接顺序,只要保持r从小到大或者r从大到小都是可以的。

注意:由于需要将每条边的两个节点进行编号,所以用并查集的时候初始化范围从0到2*n而不是n。因为每条边有两个点。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5 + 10;
 5 int n, m;
 6 struct node//存储操作
 7 {
 8     int u, v, id;
 9     ll c, r;
10 }a[maxn];
11 bool cmp1(const node& a, const node& b)
12 {
13     if(a.r == b.r)return a.c > b.c;
14     return a.r > b.r;//最大生成树
15 }
16 bool cmp2(const node& a, const node& b)
17 {
18     if(a.r == b.r)return a.c < b.c;
19     return a.r < b.r;
20 }
21 int fa[maxn];
22 int Find(int x)
23 {
24     return x == fa[x] ? x : fa[x] = Find(fa[x]);
25 }
26 map<int, int>ID;
27 int cnt;
28 int getID(int x)
29 {
30     if(ID[x])return ID[x];
31     return ID[x] = ++cnt;
32 }
33 int main()
34 {
35     while(scanf("%d", &n) != EOF)
36     {
37         ID.clear();
38         cnt = 0;//计数
39         for(int i = 1; i <= n; i++)
40         {
41             scanf("%d%d%lld%lld", &a[i].u, &a[i].v, &a[i].r, &a[i].c);
42             a[i].u = getID(a[i].u);
43             a[i].v = getID(a[i].v);
44             a[i].id = i;
45         }
46         for(int i = 1; i <= cnt; i++)
47             fa[i] = i;
48         sort(a + 1, a + 1 + n, cmp1);
49         ll ans = 0;
50         for(int i = 1; i <= n; i++)
51         {
52             if(Find(a[i].u) != Find(a[i].v))
53             {
54                 ans += a[i].c;
55                 fa[Find(a[i].u)] = Find(a[i].v);
56             }
57         }
58         sort(a + 1, a + 1 + n, cmp2);
59         printf("%lld\n%d", ans, a[1].id);
60         for(int i = 2; i <= n; i++)
61             printf(" %d", a[i].id);
62         puts("");
63     }
64     return 0;
65 }

 

posted @ 2018-07-16 22:03  _努力努力再努力x  阅读(253)  评论(0编辑  收藏  举报