標籤:sam 最小 ima -o badge pac cout clu 輸出
題目描述
如題,給出一個無向圖,求出最小產生樹,如果該圖不連通,則輸出orz
輸入輸出格式輸入格式:
第一行包含兩個整數N、M,表示該圖共有N個結點和M條無向邊。(N<=5000,M<=200000)
接下來M行每行包含三個整數Xi、Yi、Zi,表示有一條長度為Zi的無向邊串連結點Xi、Yi
輸出格式:
輸出包含一個數,即最小產生樹的各邊的長度之和;如果該圖不連通則輸出orz
輸入輸出範例輸入範例#1: 複製
4 51 2 21 3 21 4 32 3 43 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
#include<bits/stdc++.h>using namespace std;struct node{ int x,y; int val;}st[200009]; int r[100009];int n,m;int sum;bool cmp(node a,node b){ return a.val<b.val;}int f(int k){ if(r[k]==k)return k; return r[k]=f(r[k]);}//並查集,確定根節點int main(){ cin>>n>>m; for(int i=1;i<=n;i++)r[i]=i; for(int i=1;i<=m;i++)cin>>st[i].x>>st[i].y>>st[i].val; sort(st+1,st+1+m,cmp);//以邊權排序 for(int i=1;i<=m;i++){ int tx=f(st[i].x),ty=f(st[i].y); if(tx==ty)continue;//已經是一個集合就跳過 r[ty]=r[tx]; sum+=st[i].val; } int flag=0; for(int i=1;i<=n;i++)if(r[i]==i)flag++;//判斷是否連完,若根節點大於1則沒連完 if(flag==1)cout<<sum<<endl; else cout<<"orz"<<endl; return 0;}
最小產生樹(模版)