【Luogu P2502】[HAOI2006]旅行
阿新 • • 發佈:2020-07-21
題目大意:
給定一個有 \(n\) 個點的無向圖,求出從 \(s\) 到 \(t\) 的最大權值與最小權值的比。
正文:
並查集查詢 \(s\) 與 \(t\) 是否連通,可以通過給鄰接表按權值從大到小排序,列舉每次連通的最大最小權值比即可。
程式碼:
int find_(int x) {if(x == fa[x])return x;return fa[x] = find_(fa[x]);} void Add(int u, int v, int w) { e[++tot] = (node){u, v, head[u], w}, head[u] = tot; } bool cmp(node a, node b) { return a.w > b.w; } int gcd(int a, int b) { if(b == 0) return a; return gcd(b, a%b); } int main() { scanf ("%d%d", &n, &m); for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 1; i <= m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); Add(u, v, w); fa[find_(u)] = find_(v); } scanf ("%d%d", &s, &t); if(find_(s) != find_(t)) { puts("IMPOSSIBLE"); return 0; } sort (e + 1, e + 1 + tot, cmp); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) fa[j] = j; for (int j = i; j <= m; j++) { int u = e[j].from, v = e[j].to; fa[find_(u)] = find_(v); if(find_(s) == find_(t)) { double opt = e[i].w * 1.0 / e[j].w * 1.0; if(opt < ans) maxsp = e[i].w, minsp = e[j].w, ans = opt; break; } } } if(maxsp % minsp) printf("%d/%d", maxsp / gcd(maxsp, minsp), minsp / gcd(maxsp, minsp)); else printf("%d", maxsp / minsp); return 0; }