魔法跳舞链 (最小生成树)

个人心得:周测的时候心情有点闷,看到就不想去做,比完后第二天拿着一做,这么简单,我也是醉了。

虽然最后一周了,但是我还是希望你能稳住别被其他事扰乱军心了,希望以后的你能够静下心去思考。

这题:就是用Kruskal算法第一遍找出最大值中的最小值,第二次再反过来用一次就好了。

这样阴沉的天气持续下去,我们不免担心起他的健康。
 
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,表示符合条件的魔法阵的魔力值之和。Sample Input

4 6
1 2 3
1 3 1
1 4 7
2 3 4
2 4 5
3 4 6

Sample Output

12
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int magic[100005];
 6 int n,m;
 7 struct power
 8 {
 9     int u,v,q;
10 }p[100005*2];
11 bool cmp(power a,power b){
12      return a.q<b.q;
13 }
14 void init()
15 {
16     for(int i=1;i<=n;i++)
17         magic[i]=i;
18 }
19 int getm(int x){
20    if(x!=magic[x])
21       magic[x]=getm(magic[x]);
22    return magic[x];
23 }
24 void marge(int x,int y){
25     int p=getm(x),q=getm(y);
26     if(p!=q)
27        magic[p]=q;
28 }
29 int main(){
30     scanf("%d%d",&n,&m);
31     init();
32     for(int i=1;i<=m;i++)
33         scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].q);
34         sort(p+1,p+m+1,cmp);
35         int maxn=0;
36         long long oo=0;
37         int flag=0;
38         for(int i=1;i<=m;i++){
39             if(getm(p[i].u)==getm(p[i].v)) continue;
40             marge(p[i].u,p[i].v);
41             if(maxn<p[i].q)
42             {
43                 maxn=p[i].q;
44                 flag=i;
45             }
46         }
47         init();
48         for(int i=m;i>=1;i--)
49         {
50             if(p[i].q>maxn) continue;
51             if(getm(p[i].u)==getm(p[i].v)) continue;
52             marge(p[i].u,p[i].v);
53             oo+=p[i].q;
54 
55         }
56 
57          printf("%lld\n",oo);
58 
59   return 0;
60 }

 



posted @ 2017-08-22 08:24  余生漫漫浪  阅读(270)  评论(0编辑  收藏  举报