1. 程式人生 > >旅行comf BZOJ

旅行comf BZOJ

題目傳送門

思路:這個題先把所有的邊從小到大排序,然後列舉起點,然後就可以用Kruskal來加邊,直到s和t聯通,這樣求出來最小的比值。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string> #include <vector> #define MAXN 10010 #define MAXE 40 #define INF 0x7fffff #define MOD 100003 #define LL long long #define ULL unsigned long long #define pi 3.14159 using namespace std; int par[MAXN]; int rank1[MAXN]; void init(int n) { for (int i = 0; i <= n; ++i) { par[i] = i; rank1[i] = 0
; } } int find(int x) { if (x == par[x]) return x; return par[x] = find(par[x]); } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) return; if (rank1[y] > rank1[x]) par[x] = y; else { par[y] = x; if (rank1[x] == rank1[y]) rank1[x]++; } } int
gcd(int a, int b) { if (b == 0) { return a; } else { return gcd(b, a % b); } } struct Node { int start; int end; int cost; }road[MAXN]; bool cmp(const Node &x1, const Node &x2) { return x1.cost < x2.cost; } int main() { std::ios::sync_with_stdio(false); int n, m, s, t; //int x, y, z; cin >> n >> m; for (int i = 0; i < m; ++i) { cin >> road[i].start >> road[i].end >> road[i].cost; } cin >> s >> t; sort(road, road + m, cmp); int max_length = 0, min_length = INF; double ans = INF; bool flag = false; int order_min, order_max; for (int i = 0; i < m; ++i) { init(n); min_length = road[i].cost; for (int j = i; j < m; ++j) { if (find(road[j].start) != find(road[j].end)) { unite(road[j].start, road[j].end); } if (find(s) == find(t)) { max_length = road[j].cost; if (1.0 * max_length / min_length < ans) { ans = 1.0 * max_length / min_length; order_min = min_length; order_max = max_length; } flag = true; break; } } } if (flag) { int g = gcd(order_max, order_min); order_min /= g, order_max /= g; if (order_min == 1) { cout << order_max << endl; } else { cout << order_max << "/" << order_min << endl; } } else { cout << "IMPOSSIBLE\n"; } return 0; }