POJ 3522 Slim Span(最瘦生成树)
题目:http://poj.org/problem?id=3522
题意:给你一张无向图,让你找出所有生成树中,其最大权值边与最小权值边差最小的一棵树,并输出这个值,如果没有的话
输出0.
思路:依次枚举最小边,用Kruskal算法求出最小生成树,记录其差值,并逐个比较,求出最小的。
AC代码如下:
1 #include<cstdio>
2 #include<algorithm>
3 #include<iostream>
4 using namespace std;
5 #define MaxN 105
6 #define MaxM 5010
7 #define INF 2100000
8 int m,n,edgecnt;
9 int path[MaxN];
10 struct EDGE
11 {
12 int u,v,length;
13 }edge[MaxM];
14
15 bool cmp(const EDGE &A,const EDGE &B)
16 {
17 return A.length<B.length;
18 }
19
20 void Addedge(int u,int v,int len)
21 {
22 edge[edgecnt].u=u;
23 edge[edgecnt].v=v;
24 edge[edgecnt].length=len;
25 ++edgecnt;
26 return ;
27 }
28
29 void Set()
30 {
31 for(int i=1;i<=n;i++)
32 path[i]=i;
33 return;
34 }
35
36 int Find_path(int x)
37 {
38 if(x!=path[x]) path[x]=Find_path(path[x]);
39 return path[x];
40 }
41 int Kruskal(int start)
42 {
43 int cnt=0,x,y;
44 int max;
45 sort(edge,edge+m,cmp);
46 Set();
47 for(int i=start;i<m && cnt<n-1;i++)
48 {
49 x=Find_path(edge[i].u);
50 y=Find_path(edge[i].v);
51 if(x==y)
52 continue;
53 path[x]=path[y];
54 max=edge[i].length;
55 ++cnt;
56 }
57 return cnt<n-1?INF:max-edge[start].length;
58 }
59 int main()
60 {
61 int u,v,w,i,en,minans,temp;
62 while(scanf("%d %d",&n,&m)&&(n!=0 ||m!=0))
63 {
64 temp=0;
65 edgecnt=0;
66 minans=INF;
67 memset(edge,0,sizeof(edge));
68 memset(path,0,sizeof(path));
69 for(i=0;i<m;i++)
70 {
71 scanf("%d %d %d",&u,&v,&w);
72 Addedge(u,v,w);
73 }
74 for(i=0;i<=m-n+1;i++)
75 {
76 temp=Kruskal(i);
77 if(temp<minans) minans=temp;
78 }
79 printf("%d\n",minans<INF?minans:-1);
80 }
81 return 0;
82 }