POJ 3522 Slim Span (Kruskal枚举最小边)

题意:

求出最小生成树中最大边与最小边差距的最小值。

分析:

排序,枚举最小边, 用最小边构造最小生成树, 没法构造了就退出

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <queue>
 8 #include <set>
 9 #include <map>
10 #include <cstring>
11 #include <cmath>
12 #include <iomanip>
13 #define rep(i,a,b) for(int i = a; i < b;i++)
14 #define _rep(i,a,b) for(int i = a; i <= b;i++)
15 using namespace std;
16 const int inf = 1e9 + 7;
17 const int maxn = 100 + 7;
18 int n , m, cnt;
19 struct edge{
20     int u, to , d;
21     bool operator < (const edge& a) const {
22         return d < a.d;
23     }
24 }G[maxn * maxn];
25 int f[maxn];
26 void init(){
27     _rep(i,1,n) f[i] = i;
28 }
29 int get(int x){
30     if(f[x] == x){
31         return x;
32     }else{
33         f[x] = get(f[x]);
34         return f[x];
35     }
36 }
37 void merge(int a, int b){
38     int t1 = get(a), t2 = get(b);
39     if(t1 != t2){
40         f[t2] = t1;
41     }
42 }
43 int Kruskal(int st){
44     int picked = 0;
45     int min_d = inf, max_d = -inf;
46     rep(i,st,m){
47         int u = G[i].u, v = G[i].to, d = G[i].d;
48         if(get(u) != get(v)){
49             merge(u,v);
50             picked++;
51             min_d = min(min_d, d), max_d = max(max_d , d);
52         }
53         if(picked == n - 1) return max_d - min_d;//已经构造出最小生成树, 返回结果
54     }
55     return -1;//已经无法构造生成树了, 结束枚举
56 }
57 int main(){
58 //    freopen("1.txt","r", stdin);
59     while(cin >> n >> m && n){
60         cnt = 0;
61         rep(i,0,m){
62             int u , v , d;
63             cin >> u >> v >> d;
64             G[cnt].u = u , G[cnt].to = v, G[cnt].d = d;
65             cnt++;
66         }
67         sort(G, G + cnt);
68         int ans = inf;
69         for(int i = 0; i < m - n + 2;  i++){ //由于至少要n-1条边, 所以枚举到m - n + 1
70             init();
71             int t = Kruskal(i);
72             if(t != -1){
73                 ans = min(ans, t);
74             }else break;
75         }
76         printf("%d\n", ans == inf ? -1 : ans);
77     }
78 }

 

转载于:https://www.cnblogs.com/Jadon97/p/8353880.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值