CODEVS 1001 舒适的路线
1001 舒适的路线
给定一张图, 起点, 终点, 每条边有一个舒适值, 求从起点到终点最大舒适值 \(/\) 最小舒适值 最小
错误日志: 存 \(double\) 时等号右边没有强制转类型
Solution
一个数 \(\frac{x}{y}\) 值最小, 可以想到使 \(x, y\) 的值越接近, 其分数值越小
数据范围不大, 排序后考虑枚举最小边
当加边加到图联通时, 最后一条边即为最大边, 更新答案即可
加边可以用并查集维护
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#define LL long long
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 100019, INF = 1e9 + 19;;
int num, nr;
struct Node{
int u, v, dis;
}I[maxn];
bool cmp(Node a, Node b){return a.dis < b.dis;}
int father[maxn];
int findfather(int v){
if(father[v] == v)return v;
return father[v] = findfather(father[v]);
}
void init(){
for(int i = 1;i <= num;i++)father[i] = i;
}
int s, t, minn = -1, maxx;
double ans = INF;
int work(int INDEX){
init();
for(int i = INDEX;i <= nr;i++){
int faA = findfather(I[i].u), faB = findfather(I[i].v);
if(father[faA] != father[faB]){
father[faA] = father[faB];
}
if(findfather(s) == findfather(t))return I[i].dis;
}
return -1;
}
int gcd(int a, int b){
return !b ? a : gcd(b, a % b);
}
int main(){
num = RD(), nr = RD();
for(int i = 1;i <= nr;i++)I[i].u = RD(), I[i].v = RD(), I[i].dis = RD();
s = RD(), t = RD();
sort(I + 1, I + 1 + nr, cmp);
for(int i = 1;i <= nr;i++){
int res = work(i);
if(res == -1)break;
double temp = (double)res / I[i].dis;
if(temp < ans){
ans = temp;
maxx = res;
minn = I[i].dis;
}
}
if(minn == -1){puts("IMPOSSIBLE");return 0;}
if(maxx % minn == 0){printf("%d\n", maxx / minn);return 0;}
int d = gcd(minn, maxx);
printf("%d/%d\n", maxx / d, minn / d);
return 0;
}