3522

1 /*
2 最小生成树
3
4 可用克鲁斯卡尔算法
5
6 可枚举最短边
7 */
8
9 // include file
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cstring>
13 #include <cmath>
14 #include <cctype>
15 #include <ctime>
16
17 #include <iostream>
18 #include <sstream>
19 #include <fstream>
20 #include <iomanip>
21 #include <bitset>
22 #include <strstream>
23
24 #include <algorithm>
25 #include <string>
26 #include <vector>
27 #include <queue>
28 #include <set>
29 #include <list>
30 #include <functional>
31
32 using namespace std;
33
34 // typedef
35 typedef long long LL;
36 typedef unsigned long long ULL;
37
38 //
39 #define read freopen("in.txt","r",stdin)
40 #define write freopen("out.txt","w",stdout)
41 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
42 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
43 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
44 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
45 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
46 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
47 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
48
49 #define FF(i,a) for(int i=0;i<(a);i+++)
50 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
51 #define Z(a) (a<<1)
52 #define Y(a) (a>>1)
53
54 const double eps = 1e-6;
55 const double INFf = 1e10;
56 const int INFi = 1000000000;
57 const double Pi = acos(-1.0);
58
59 template<class T> inline T sqr(T a){return a*a;}
60 template<class T> inline T TMAX(T x,T y)
61 {
62 if(x>y) return x;
63 return y;
64 }
65 template<class T> inline T TMIN(T x,T y)
66 {
67 if(x<y) return x;
68 return y;
69 }
70 template<class T> inline void SWAP(T &x,T &y)
71 {
72 T t = x;
73 x = y;
74 y = t;
75 }
76 template<class T> inline T MMAX(T x,T y,T z)
77 {
78 return TMAX(TMAX(x,y),z);
79 }
80
81
82 // code begin
83 #define MAXN 110
84 int rank[MAXN],father[MAXN];
85 int N,M,ans;
86 struct node
87 {
88 int s;
89 int e;
90 int w;
91 friend bool operator<(node a,node b)
92 {
93 return a.w<b.w;
94 }
95 };
96 node edge[MAXN*MAXN];
97
98 void Init()
99 {
100 FORi(1,N+1,1)
101 {
102 rank[i] = 1;
103 father[i] = i;
104 }
105 }
106
107 int find(int i)
108 {
109 if(father[i]!=i)
110 father[i] = find(father[i]);
111 return father[i];
112 }
113
114 void Joint(int a,int b)
115 {
116 a = find(a);
117 b = find(b);
118 if(a==b) return;
119 if(rank[a]>rank[b])
120 {
121 father[b] = a;
122 rank[a]+=rank[b];
123 }
124 else
125 {
126 father[a]=b;
127 rank[b]+=rank[a];
128 }
129 }
130 int MST_kruskal(int j) //最小的一个边
131 {
132 Init();
133 int mst = 0;
134 int Gmax = 0;
135 FORi(j,M,1)
136 {
137 if(mst==N-1)
138 break;
139
140 if( find(edge[i].s)!=find(edge[i].e) )
141 {
142 //联合
143 Joint(edge[i].s,edge[i].e);
144 Gmax = TMAX(Gmax,edge[i].w);
145 mst++;
146 }
147
148 }
149 if(mst==N-1)
150 {
151 return Gmax-edge[j].w;
152 }
153 else
154 return -1;
155 }
156
157 int main()
158 {
159 read;
160 write;
161 int Emin,Emax;
162 while(scanf("%d %d",&N,&M)!=-1)
163 {
164 if(N+M==0) break;
165 Emin = INFi;
166 Emax = 0;
167 FORi(0,M,1)
168 {
169 scanf("%d %d %d",&edge[i].s,&edge[i].e,&edge[i].w);
170 Emin = TMIN(edge[i].w,Emin);
171 Emax = TMAX(edge[i].w,Emax);
172 }
173 sort(edge,edge+M);
174
175 int first = MST_kruskal(0);
176 if(first<=0)
177 {
178 printf("%d\n",first);
179 continue;
180 }
181 ans = first;
182 FORi(1,M,1)
183 {
184 first = MST_kruskal(i);
185 if(first==0)
186 {
187 ans = 0;
188 break;
189 }
190 if(first!=-1)
191 ans = TMIN(ans,first);
192 }
193 printf("%d\n",ans);
194 }
195 return 0;
196 }
posted @ 2011-03-08 09:59  AC2012  阅读(911)  评论(0编辑  收藏  举报