洛谷P1195 口袋的天空 并查集

洛谷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 }

 

posted @ 2017-08-29 19:51  third2333  阅读(132)  评论(0编辑  收藏  举报