思路:枚举所有可能的情况。
枚举最小边, 然后不断加边, 直到联通后, 这个时候有一个生成树。这个时候,在目前这个最小边的情况可以不往后枚举了,
可以直接更新答案后break。
因为题目求最大边减最小边最小, 在最小边确定的情况下, 要使得差值最小, 就要使得最大边最小, 那么排序之后加边后
的第一个生成树一定是此情况下的最优解, 因为这个时候最大边最小, 后面的边肯定更大。
细节(1)注意题目给的点标号从1开始还是从0开始。(2)边数组可以用vector(3)find函数最后 return f[x]。
#include<cstdio>
#include<vector>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;const int MAXN = 112;
struct node
{int w, u, v;node(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {}bool operator < (const node& rhs) const{return w < rhs.w;}
};
vector<node> Edge;
int f[MAXN], n, m;int find(int x)
{if(f[x] != x)f[x] = find(f[x]);return f[x];
}int main()
{while(~scanf("%d%d", &n, &m) && n){Edge.clear();REP(i, 0, m){int u, v, w;scanf("%d%d%d", &u, &v, &w);Edge.push_back(node(u, v, w));}sort(Edge.begin(), Edge.end());int ans = 1e9;REP(L, 0, m){int sum = 0;REP(i, 1, n + 1) f[i] = i;REP(R, L, m){int u = find(Edge[R].u), v = find(Edge[R].v);if(u != v) {f[u] = v;if(++sum == n - 1){ans = min(ans, Edge[R].w - Edge[L].w);break;}}}}printf("%d\n", ans == 1e9 ? -1 : ans);}return 0;
}