[HAOI2006]旅行COMF
根据数据范围求解,有,好了,直接暴力
贪心地选择一段
值连续的边,然后判断
是否联通即可。
所以我们只要预先对边按照排个序,然后用并查集判断
是否联通即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10;
struct Edge {
int x, y, w;
Edge(int _x = 0, int _y = 0, int _w = 0) : x(_x), y(_y), w(_w) {}
void read() {
scanf("%d %d %d", &x, &y, &w);
}
bool operator < (const Edge &t) const {
return w > t.w;
}
}a[N];
int n, m, s, t, fa[N];
void init() {
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
}
int find(int rt) {
return rt == fa[rt] ? rt : fa[rt] = find(fa[rt]);
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
a[i].read();
}
scanf("%d %d", &s, &t);
sort(a + 1, a + 1 + m);
const int inf = 0x3f3f3f3f;
int ans_max = inf, ans_min = 1;
for (int i = 1; i <= m; i++) {
int cur_max = a[i].w, cur_min = inf, flag = 0;
init();
for (int j = i; j <= m; j++) {
int fx = find(a[j].x), fy = find(a[j].y);
if (fx != fy) {
fa[fx] = fy;
}
if (find(s) == find(t)) {
cur_min = a[j].w;
flag = 1;
break;
}
}
if (flag) {
if ((double)cur_max / cur_min < (double)ans_max / ans_min) {
ans_max = cur_max;
ans_min = cur_min;
}
}
}
if (ans_max == inf) {
puts("IMPOSSIBLE");
}
else {
int d = __gcd(ans_max, ans_min);
if (d == ans_min) {
printf("%d\n", ans_max / d);
}
else {
printf("%d/%d\n", ans_max / d, ans_min / d);
}
}
return 0;
} 
京公网安备 11010502036488号