1. 程式人生 > >洛谷 P3366 【模板】最小生成樹 如題

洛谷 P3366 【模板】最小生成樹 如題

content logs radius 包含 bre sample pri summary pac

P3366 【模板】最小生成樹

  • 時空限制1s / 128MB

題目描述

如題,給出一個無向圖,求出最小生成樹,如果該圖不連通,則輸出orz

輸入輸出格式

輸入格式:

第一行包含兩個整數N、M,表示該圖共有N個結點和M條無向邊。(N<=5000,M<=200000)

接下來M行每行包含三個整數Xi、Yi、Zi,表示有一條長度為Zi的無向邊連接結點Xi、Yi

輸出格式:

輸出包含一個數,即最小生成樹的各邊的長度之和;如果該圖不連通則輸出orz

輸入輸出樣例

輸入樣例#1:
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
輸出樣例#1:
7

說明

時空限制:1000ms,128M

數據規模:

對於20%的數據:N<=5,M<=20

對於40%的數據:N<=50,M<=2500

對於70%的數據:N<=500,M<=10000

對於100%的數據:N<=5000,M<=200000

樣例解釋:

技術分享

所以最小生成樹的總邊權為2+2+3=7

------------------------------------------------------------------------------------------------------------

Kruskal(並查集+貪心實現):

技術分享
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define maxn 233333
 6 using namespace std;
 7 struct node{
 8     int fr,to,w;
 9 };
10 node e[maxn];
11 int n,m,cnt,num,fa[maxn],ans;
12 bool cmp(node,node);
13 int
getf(int); 14 int main(){ 15 scanf("%d %d",&n,&m); 16 for(int i=1;i<=n;i++) fa[i]=i; 17 cnt=0;num=0;ans=0; 18 for(int i=1;i<=m;i++){ 19 int x,y,z; 20 scanf("%d %d %d",&x,&y,&z); 21 e[++cnt].fr=x;e[cnt].to=y;e[cnt].w=z; 22 } 23 sort(e+1,e+1+m,cmp); 24 for(int i=1;i<=m;i++){ 25 if(num==n-1) break; 26 int af,bf; 27 af=getf(e[i].fr); 28 bf=getf(e[i].to); 29 if(af!=bf){ 30 fa[af]=bf; 31 num++; 32 ans+=e[i].w; 33 } 34 } 35 if(num<n-1) printf("orz"); 36 else printf("%d",ans); 37 return 0; 38 } 39 int getf(int x){ 40 if(fa[x]==x) return x; 41 return fa[x]=getf(fa[x]); 42 } 43 bool cmp(node x,node y){ 44 return x.w<y.w; 45 }
Kruskal

洛谷 P3366 【模板】最小生成樹 如題