[POJ3522 Slim Span]

[题目来源]:Japan 2007

[关键字]:图论 最小生成树

[题目大意]:求一棵生成树让最大边最小边差值最小

//=====================================================================================================

[分析]:首先将边进行排序,然后依次枚举么一个边作为生成树中的最小边利用克鲁斯卡尔算法求最小生成树,如果此时求出的结果由于之前的值就更新。因为克鲁斯卡尔算法就是每次取可以取的最小边加入生成树中,所以利用它求出来的最小生成树一定是以枚举的边作为最小边的所有可能值中最优的。

[代码]:

View Code
 1 type
2 rec = record
3 x, y, d: longint;
4 end;
5
6 var
7 n, m, i, now, ans, min, max: longint;
8 e: array[0..55010] of rec;
9 f: array[0..1000] of longint;
10
11 procedure qs(l, r: longint);
12 var
13 i, j, mid: longint;
14 t: rec;
15 begin
16 i := l;
17 j := r;
18 mid := e[(l+r) div 2].d;
19 repeat
20 while e[i].d < mid do inc(i);
21 while e[j].d > mid do dec(j);
22 if i <= j then
23 begin
24 t := e[i];
25 e[i] := e[j];
26 e[j] := t;
27 inc(i);
28 dec(j);
29 end;
30 until i > j;
31 if l < j then qs(l,j);
32 if i < r then qs(i,r);
33 end;
34
35 function get(k: longint):longint;
36 begin
37 if f[k] = k then exit(k);
38 f[k] := get(f[k]);
39 get := f[k];
40 end;
41
42 procedure kur(st: longint);
43 var
44 i, p, x, y: longint;
45 begin
46 p := 0;
47 for i := 1 to n do f[i] := i;
48 i := st;
49 min := e[st].d;
50 while (p < n-1) or (i <= m) do
51 begin
52 x := get(e[i].x);
53 y := get(e[i].y);
54 if x <> y then
55 begin
56 f[x] := y;
57 max := e[i].d;
58 inc(p);
59 end;
60 inc(i);
61 end;
62 if p <> n-1 then now := maxlongint else now := max-min;
63 end;
64
65 begin
66 readln(n,m);
67 while not((n = 0) and (m = 0)) do
68 begin
69 fillchar(e,sizeof(e),0);
70 for i := 1 to m do
71 readln(e[i].x,e[i].y,e[i].d);
72 qs(1,m);
73 ans := maxlongint;
74 for i := 1 to m-n+2 do
75 begin
76 kur(i);
77 if now < ans then ans := now;
78 end;
79 if ans = maxlongint then writeln(-1) else writeln(ans);
80 readln(n,m);
81 end;
82 end.



转载于:https://www.cnblogs.com/procedure2012/archive/2011/11/02/2233216.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值