1. 程式人生 > >魔法跳舞鏈 (最小生成樹)

魔法跳舞鏈 (最小生成樹)

心得 pan 靜下心 logs sin tin ace sca !=

個人心得:周測的時候心情有點悶,看到就不想去做,比完後第二天拿著一做,這麽簡單,我也是醉了。

雖然最後一周了,但是我還是希望你能穩住別被其他事擾亂軍心了,希望以後的你能夠靜下心去思考。

這題:就是用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 }



魔法跳舞鏈 (最小生成樹)