1. 程式人生 > >洛谷P1195 口袋的天空 並查集

洛谷P1195 口袋的天空 並查集

oid blog div == get algo nbsp i++ sin

洛谷P1195 口袋的天空

並查集
將邊從小到大排序,然後依次加邊 看看是否能變成 K 個連通塊,
以及其最小話費

 1 #include <cstdio>
 2 #include <algorithm> 
 3 #define For(i,j,k) for(int i=j;i<=k;i++)  
 4 using namespace std ; 
 5 
 6 const int N = 1011,M = 10011,inf = 1e9 ;
 7 struct edge{
 8     int x,y,val ; 
 9 }e[M] ; 
10 
11 int
n,m,k,sum,num ; 12 int fa[N] ; 13 14 inline int read() 15 { 16 int x = 0 , f = 1 ; 17 char ch = getchar() ; 18 while(ch<0||ch>9) { if(ch==-) f = -1 ; ch = getchar() ; } 19 while(ch>=0&&ch<=9) { x = x * 10+ch-48 ; ch = getchar() ; } 20 return x * f ;
21 } 22 23 inline bool cmp(edge a,edge b) 24 { 25 return a.val < b.val ; 26 } 27 28 inline int find(int x) 29 { 30 if(fa[x]==x) return x ; 31 return fa[ x ] = find(fa[x]) ; 32 } 33 34 inline void work() 35 { 36 int x,y ; 37 num = 0 ; sum = 0 ; 38 sort(e+1,e+m+1,cmp) ;
39 For(i,1,m) { 40 x = find(e[ i ].x) ; 41 y = find(e[ i ].y) ; 42 if(x!=y) { 43 num++ ; sum+=e[ i ].val ; 44 if(num==n-k) { 45 printf("%d\n",sum) ; 46 return ; 47 } 48 fa[x] = y ; 49 } 50 } 51 printf("No Answer\n") ; 52 } 53 54 int main() 55 { 56 while(~scanf("%d%d%d",&n,&m,&k)) { 57 For(i,1,n) fa[ i ] = i ; 58 For(i,1,m) { 59 e[ i ].x = read() ; e[ i ].y = read() ; e[ i ].val = read() ; 60 } 61 work() ; 62 } 63 return 0 ; 64 }

洛谷P1195 口袋的天空 並查集