给你一个图,
求一个生成树, 边权Max – Min 要最小,输出最小值, 不能构成生成树的 输出 -1;
思路:
Keuksal 算法, 先排序边, 然后枚举 第一条边, 往后加入边, 直到有 n-1 条边的树, 求出那个值, 把可能的值取MIN;
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; const int maxn = 100 + 7; set<int> NUM; struct Edges { int u, v; int val; bool operator < (const Edges a) const { return val < a.val; } }E[maxn * maxn]; int Pre[maxn]; int cnt,Max,n,m; void ADD(int u,int v,int val) { E[cnt].u = u, E[cnt].v = v, E[cnt].val = val; cnt++; } void Init() { for(int i = 0; i < maxn; ++i) Pre[i] = i; } int Find(int x) { int r = x; while(r != Pre[r]) r = Pre[r]; return Pre[x] = r; } bool Union(int x,int y) { int ax = Find(x), ay = Find(y); if(ax == ay) return false; // if(ax == x || ay == y) CC--; Pre[ax] = ay; // CC += 2; return true; } bool MST (int x) { int num = 0; Max = -1; for(int i = 0; i < maxn; ++i) Pre[i] = i; for(int i = x; i < m; ++i) { int a = Find(E[i].v), b = Find(E[i].u); if(a == b) continue; Pre[a] = b; Max = max(Max,E[i].val); if(++num == n-1) return true; } return false; } int main() { while(~scanf("%d%d",&n,&m) && (n + m)) { cnt = 0; int a, b, c; for(int i = 0; i < m; ++i) { scanf("%d%d%d",&a,&b,&c); ADD(a,b,c); } int ans = 999999999; sort(E,E+m); for(int i = 0; i < m; ++i) { if(MST(i)) { ans = min(ans, Max - E[i].val); } } if(ans == 999999999) ans = -1; printf("%d\n",ans); } return 0; }