UVa 1395 (最小生成树) Slim Span

题意:

规定一棵生成树的苗条度为:最大权值与最小权值之差。给出一个n个顶点m条边的图,求苗条度最小的生成树。

分析:

按照边的权值排序,枚举边集的连续区间[L, R]的左边界L,如果这些区间刚好满足一个生成树,则存在一个苗条度不超过W[R] - W[L]的生成树。

话说,代码中用了STL的vector,慢了很多。

 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int INF = 1000000000;
 7 const int maxn = 100 + 10;
 8 int pa[maxn];
 9 
10 int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }
11 
12 struct Edge
13 {
14     int u, v, w;
15     Edge(int u, int v, int w):u(u), v(v), w(w) {}
16     bool operator < (const Edge& rhs) const
17     {
18         return w < rhs.w;
19     }
20 };
21 
22 vector<Edge> G;
23 
24 int main()
25 {
26     //freopen("in.txt", "r", stdin);
27     int n, m;
28     while(scanf("%d%d", &n, &m) == 2 && n)
29     {
30         G.clear();
31         int u, v, w;
32         for(int i = 0; i < m; ++i)
33         {
34             scanf("%d%d%d", &u, &v, &w);
35             G.push_back(Edge(u, v, w));
36         }
37         sort(G.begin(), G.end());
38         int ans = INF;
39         for(int L = 0; L <= m - n + 1; ++L)
40         {
41             for(int i = 1; i <= n; ++i) pa[i] = i;
42             int cnt = n;
43             for(int R = L; R < m; ++R)
44             {
45                 int u = findset(G[R].u), v = findset(G[R].v);
46                 if(u != v)
47                 {
48                     pa[u] = v;
49                     if(--cnt == 1) { ans = min(ans, G[R].w - G[L].w); }
50                 }
51             }
52         }
53         if(ans == INF) ans = -1;
54 
55         printf("%d\n", ans);
56     }
57 
58     return 0;
59 }
代码君

 

posted @ 2015-01-04 12:33  AOQNRMGYXLMV  阅读(308)  评论(0编辑  收藏  举报