Description
求苗条度最小的生成树
苗条度指该生成树的最大边 - 最小边
Algorithm
Kruskal变形
先sort
然后枚举最小边 构建最小生成树
Hint
UVa JAVA的RE 不知道为何= =
POJ的JAVA才1.5 λ表达式是JAVA 1.8才有的 然后本人才疏学浅 除了λ表达式以外不会写自定义sort比较 所以CE = =
C++就过了
会了C++ 的INF写法
#include <climits>
这样就有
INT_MAX这个常量了
Code
#include <cstdio>
#include <climits>
#include <algorithm>
using namespace std;
struct Edge
{
int u, v, w;
Edge(){}
Edge(int u, int v, int w) : u(u), v(v), w(w) {}
};
const int MAX_M = 109 * 108 / 2;
const int MAX_N = 100 + 9;
int n;
bool comp(Edge a, Edge b)
{
if (a.w < b.w) return true; else return false;
}
struct UnionFind
{
int n;
int par[MAX_N];
int rank[MAX_N];
UnionFind(int nn)
{
n = nn;
for (int i = 0; i < n; i++) {
par[i] = i;
rank[i] = i;
}
}
int find(int x)
{
if (par[x] == x) return x;
else return par[x] = find(par[x]);
}
void unite(int x, int y)
{
x = find(x);
y = find(y);
if (x == y) return;
if (rank[x] < rank[y]) {
par[x] = y;
} else {
par[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
bool same(int x, int y) {
return find(x) == find(y);
}
void print()
{
for (int i = 0; i < n; i++) {
printf("%d ", par[i]);
}
}
int total()
{
int s = 0;
for (int i = 0; i < n; i++) {
if (par[i] == i) s++;
}
return s;
}
};
void solve()
{
int m;
scanf("%d", &m);
Edge edges[MAX_M];
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
edges[i] = Edge(u - 1, v - 1, w);
}
sort(edges, edges + m, comp);
UnionFind unionFind(n);
const int INF = INT_MAX / 2;
int ans = INF;
for (int i = 0; i < m; i++) {
UnionFind unionFind = UnionFind(n);
int e = 0;
for (int j = i; j < m; j++) {
if (!unionFind.same(edges[j].u, edges[j].v)) {
unionFind.unite(edges[j].u, edges[j].v);
e++;
if (e == n - 1) {
ans = min(edges[j].w - edges[i].w, ans);
break;
}
}
}
}
if (ans == INF) ans = -1;
printf("%d\n", ans);
}
int main()
{
// freopen("input.txt", "r", stdin);
for (;;) {
scanf("%d", &n);
if (n == 0) break;
solve();
}
}
时间: 2024-10-10 22:31:00