旅行comf BZOJ
阿新 • • 發佈:2019-01-02
思路:這個題先把所有的邊從小到大排序,然後列舉起點,然後就可以用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;
}