魔法跳舞鏈 (最小生成樹)
阿新 • • 發佈:2017-08-22
心得 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 }
魔法跳舞鏈 (最小生成樹)