登 录
最瘦生成树
即求生成树中最大边和最小边差值最小
/* * File: PKU 3522 Slim Span * Author: xiaotian @ hnu * Created on 2010年10月8日, 上午11:10 * 题解:最瘦生成树 */ #include<stdio.h> #include<iostream> #include<string.h> #include<queue> #include<map> #include<set> #include<math.h> using namespace std; #define N 108 #define E 5008 #define inf 0x7ffffff int fat[N]; int rank[N]; int n, m; struct node { int x, y, len; node(int a = 0, int b = 0, int c = 0) : x(a), y(b), len(c) {} bool operator<(const node & r)const { /* 这里决定是最大还是最小生成树 */ return len < r.len; /* 大于号就是最大生成树,小于号就是最小生成树 */ } }; node edge[E]; void build() { int i, a, b; int c; for (i = 0; i < m; i++) { scanf("%d%d%d", &a, &b, &c); edge[i] = node(a - 1, b - 1, c); } sort(edge, edge + m); } void Make_set() { for (int i = 0; i < n; i++) { fat[i] = i; rank[i] = 0; } } int Find_set(int x) { if (x != fat[x]) fat[x] = Find_set(fat[x]); return fat[x]; } int Union(int k) { int x, y; x = Find_set(edge[k].x); y = Find_set(edge[k].y); if (x == y) return 0; if (rank[x] > rank[y]) fat[y] = x; else { if (rank[x] == rank[y]) rank[y]++; fat[x] = y; } return edge[k].len; } bool judge() { /* 判断是否连通 */ int i; for (i = 1; i < n; i++) if (Find_set(i) != Find_set(i - 1)) return 0; return 1; } int Kruskal(int k) { int i; int ans = 0; Make_set(); for (i = k; i < m; i++) { int p = Union(i); if (p) ans = p; } if (judge()) return ans - edge[k].len; else return -1; /* 不连通,不存在生成树 */ } int main() { while (scanf("%d%d", &n, &m) != EOF) { if(n==0 && m==0) return 0; build(); int ans = Kruskal(0); if (ans == -1) { puts("-1"); continue; } for (int i = 1; i < m; i++) { int tmp = Kruskal(i); if (tmp == -1) break; if (tmp < ans) ans = tmp; } printf("%d/n", ans); } return 0; }
抱歉!评论已关闭.