思路是枚举最小边权 v,然后限定大于等于 v 的边跑 dijkstra,但是只有 50 分,求改错/证伪/hack 数据。
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
const int M = 5005;
const int INF = 2e9;
inline int read() {
int w = 1, q = 0; char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') q = q * 10 + ch - '0', ch = getchar();
return w * q;
}
struct node {
int to, w;
};
bool operator <(node x, node y) {
return x.w > y.w;
}
int n, m, e[M], dis[N];
bool vis[N];
vector <node> p[N];
priority_queue <node> q;
int dijkstra(int x, int st, int ed) {
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
q.push({st, dis[st] = 0});
while (!q.empty()) {
int t = q.top().to; q.pop();
if (vis[t]) break; vis[t] = true;
//cout << t << "\n";
for (auto j : p[t])
if (dis[j.to] > max(dis[t], j.w) && j.w >= x)
q.push({j.to, dis[j.to] = max(dis[t], j.w)});
}
return dis[ed];
}
signed main() {
// freopen("race.in", "r", stdin);
// freopen("race.out", "w", stdout);
n = read(), m = read();
for (int i = 1; i <= m; i++) {
int u = read(), v = read(), w = read();
p[u].push_back({v, w});
p[v].push_back({u, w});
e[i] = w;
}
m = unique(e + 1, e + 1 + m) - e - 1;
memset(dis, 0x3f, sizeof(dis));
int st = read(), ed = read();
int ans1 = dis[0], ans2 = 1, f = 0;
for (int i = 1; i <= m; i++) {
//t / e[i] < ans1 / ans2
int t = dijkstra(e[i], st, ed);
if (1ll * t * ans2 < 1ll * e[i] * ans1)
ans1 = t, ans2 = e[i], f = 1;
//cout << e[i] << ' ' << t << '\n';
}
if (!f) return cout << "IMPOSSIBLE", 0;
int t = __gcd(ans1, ans2);
if (ans2 == t) cout << ans1 / t << '\n';
else cout << ans1 / t << '/' << ans2 / t << '\n';
return 0;
}