畅通工程

畅通工程
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit  Status

Description

省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。 
 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。 
 

Output

对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。 
 

Sample Input

3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
 

Sample Output

3 ?
 
 1 #include<stdio.h>
 2 #include<algorithm>
 3 using namespace std;
 4 int fa[110] , n , m ;
 5 struct edge
 6 {
 7     int u , v , w ;
 8 }e[20000];
 9 
10 bool cmp (edge a , edge b)
11 {
12     return a.w < b.w ;
13 }
14 
15 int find (int x)
16 {
17     return fa[x] == x ? x : find (fa[x]) ;
18 }
19 
20 void kruskal ()
21 {
22     sort (e + 1 , e + m + 1 , cmp ) ;
23     int ans = 0 ;
24     int x , y ;
25     for (int i = 1  ; i <= m ; i++) {
26         x = find (e[i].u) ;
27         y = find (e[i].v) ;
28         if ( x != y ) {
29             ans += e[i].w ;
30             fa[x] = y ;
31         }
32     }
33     printf ("%d\n" , ans) ;
34 }
35 
36 int main ()
37 {
38    // freopen ("a.txt" , "r" , stdin ) ;
39     int x , y ;
40     int cnt ;
41     while (~ scanf ("%d" , &m ) ) {
42             if ( m == 0 )
43                 break ;
44        // printf ("n=%d, m =%d\n" , n , m ) ;
45         cnt = 0 ;
46         scanf ("%d" , &n ) ;
47         for (int i = 1 ; i <= n ; i++ )
48             fa[i] = i ;
49         for (int i = 1 ; i <= m ; i++ ) {
50             scanf ("%d%d%d" , &e[i].u , &e[i].v , &e[i].w ) ;
51             x = find (e[i].u) ;
52             y = find (e[i].v) ;
53             fa[x] = y ;
54         }
55         for (int i = 1 ; i <= n ; i++) {
56             if (fa[i] == i)
57                 cnt++ ;
58             if (cnt > 1)
59                 break ;
60         }
61         for (int i = 1 ; i <= n ; i++ )
62             fa[i] = i ;
63       //  printf ("cnt = %d\n" ,cnt) ;
64         if (cnt > 1)
65             printf ("?\n") ;
66         else
67             kruskal () ;
68     }
69     return 0 ;
70 }
union-find sets && kruskal

 

 

 

转载于:https://www.cnblogs.com/get-an-AC-everyday/p/4282256.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值