码迷,mamicode.com
首页 > 其他好文 > 详细

51nod 天气晴朗的魔法 - (Kruskall最小生成树)

时间:2017-10-31 21:28:20      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:max   return   有一个   tput   ring   output   str   pac   false   

题目:   基准时间限制:1 秒 空间限制:131072 KB 
51nod魔法学校近日开展了主题为“天气晴朗”的魔法交流活动。
 
N名魔法师按阵法站好,之后选取N - 1条魔法链将所有魔法师的魔力连接起来,形成一个魔法阵。
 
魔法链是做法成功与否的关键。每一条魔法链都有一个魔力值V,魔法最终的效果取决于阵中所有魔法链的魔力值的和。
 
由于逆天改命的魔法过于暴力,所以我们要求阵中的魔法链的魔力值最大值尽可能的小,与此同时,魔力值之和要尽可能的大。
 
现在给定魔法师人数N,魔法链数目M。求此魔法阵的最大效果。
Input
两个正整数N,M。(1 <= N <= 10^5, N <= M <= 2 * 10^5)

接下来M行,每一行有三个整数A, B, V。(1 <= A, B <= N, INT_MIN <= V <= INT_MAX)

保证输入数据合法。
Output
输出一个正整数R,表示符合条件的魔法阵的魔力值之和。
Input示例
4 6
1 2 3
1 3 1
1 4 7
2 3 4
2 4 5
3 4 6
Output示例
12

关于思路: 这道题可以先用最小生成树求出最大权值边,然后再用权值小于等于最大权值的边做一次最大生成树的做法求解

代码如下:
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 
 5 typedef long long LL;
 6 using namespace std;
 7 const int maxn=200005;
 8 struct node{
 9     LL u,v,w;
10 }edge[maxn];
11 LL f[maxn];
12 LL n,m;
13 
14 int Find(LL x)
15 {
16     if (f[x] != x)
17         f[x] = Find(f[x]);
18     return f[x];
19 }
20 
21 void Union(LL a, LL b)
22 {
23     int a1 = Find(a);
24     int b1 = Find(b);
25     if (a1 != b1)
26         f[a1] = b1;
27 }
28 bool cmp1(node a,node b)
29 {
30     return a.w>b.w;
31 }
32 bool cmp2(node a,node b)
33 {
34     return a.w<b.w;
35 }
36 int main()
37 {
38     ios::sync_with_stdio(false);
39     cin>>n>>m;
40     for(int i=1;i<=n;i++)
41         f[i]=i;
42     for(int i=0;i<m;i++)
43         cin>>edge[i].u>>edge[i].v>>edge[i].w;
44     sort(edge,edge+m,cmp2);
45     LL k=0,max_num=-1;
46     for(int i=0;i<m;i++)
47     {
48         if(Find(edge[i].u)!=Find(edge[i].v))
49         {
50             Union(edge[i].u,edge[i].v);
51             max_num = max(max_num,edge[i].w);
52             k++;
53         }
54         if(k==(n-1))
55             break;
56     }
57     sort(edge,edge+m,cmp1);
58     for(int i=1;i<=m;i++)
59         f[i]=i;
60     LL ans=0;
61     k=0;
62     for(int i=0;i<m;i++)
63     {
64         if(edge[i].w>max_num)continue;
65         if(Find(edge[i].u)!=Find(edge[i].v))
66         {
67             Union(edge[i].u,edge[i].v);
68             ans += edge[i].w;
69             k++;
70         }
71         if(k==(n-1))
72             break;
73     }
74     cout<<ans<<endl;
75     return 0;
76 }

 



51nod 天气晴朗的魔法 - (Kruskall最小生成树)

标签:max   return   有一个   tput   ring   output   str   pac   false   

原文地址:http://www.cnblogs.com/wangrunhu/p/7763509.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!