[HAOI2006]旅行
Description
Solution
做过我还不会……
就是枚举最小边然后跑MST。
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
typedef long long LL;
const int N = 500 + 10;
const int M = 5000+10;
struct Edge {
int u, v, w;
Edge(int u=0, int v=0, int w=0) : u(u), v(v), w(w) {}
} e[M];
int n, m, s, t;
int fa[N];
int mx, mn, ax, an;
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int merge(int x, int y) {
int fx = find(x), fy = find(y);
if (fx == fy) return 0;
else {
fa[fx] = fy;
return 1;
}
}
inline bool cmp(const Edge& x, const Edge &y) {
return x.w < y.w;
}
int gcd(int x, int y) {
return !y ? x : gcd(y, x%y);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1, x, y, z; i <= m; ++i) {
scanf("%d%d%d", &x, &y, &z);
e[i] = Edge(x, y, z);
}
std::sort(e+1, e+m+1, cmp);
scanf("%d%d", &s, &t);
for (int i = m; i; --i) {
mx = 0; mn = 0x3f3f3f3f;
for (int j = 1; j <= n; ++j) fa[j] = j;
// merge(u[i], v[i]);
for (int j = i; j; --j) {
if (merge(e[j].u, e[j].v)) {
mx = std::max(mx, e[j].w);
mn = std::min(mn, e[j].w);
if (find(s) == find(t)) break;
}
}
if (find(s) != find(t)) break;
// printf("%d %d\n", mx, mn);
if (!ax) ax = mx, an = mn;
else if ((double)mx / mn < (double)ax / an) ax = mx, an = mn;
}
if (ax == 0) puts("IMPOSSIBLE");
else {
if (ax % an == 0) printf("%d\n", ax / an);
else {
int g = gcd(ax, an);
printf("%d/%d\n", ax / g, an / g);
}
}
return 0;
}