题目:http://codevs.cn/problem/1001/
题解:
#include <stdio.h>
#define MaxN 500
#define MaxM 5000
#define MaxANS 0x3fffffff * 1.0
//定义全局变量道路结构体
typedef struct _Road {
int xi; //景点x
int yi; //景点y
int vi; //速度v
} Road;
Road roads[MaxM];
//定义全局变量景点集
int set[MaxN + 1];
//交换道路
void swap(int a, int b) {
Road tmp;
tmp = roads[a];
roads[a] = roads[b];
roads[b] = tmp;
}
//按速度顺序对所有道路进行排序
void sort(int m) {
int i, j;
//冒泡排序
for(i = 0; i < m; i++) {
for(j = i + 1; j < m; j++) {
if(roads[i].vi > roads[j].vi) {
swap(i, j);
}
}
}
}
//求最大公约数
int gcd(int a, int b)
{
return (((a % b) == 0) ? b : gcd(b, (a % b)));
}
// 并查集 - 查询
int find(int x) {
int r = x; //根节点值
int t;
//返回根节点值r
while(r != set[r]) {
r = set[r];
}
//压缩路径
t = x;
while(r != x) {
t = set[x];
set[x] = r;
x = t;
}
//返回根节点值r
return r;
}
// 并查集 - 合并
void union_set(int a, int b) {
int fa = find(a);
int fb = find(b);
//如果根节点值不同,则合并两集合
if(fa != fb) {
set[fa] = fb;
}
}
int main(int argc, char *argv[]) {
int n, m; //景点数,道路数
int xi, yi, vi; //道路连接景点x, y和速度v
int s, t; //起始景点,目的景点
int min, max, ansmin, ansmax; //当前路径最小值,最大值,最终最小值,最大值
double ans; //当前路径最大值,最小值比值
int i, j; //索引值
//获取数据
scanf("%d %d", &n, &m);
if((n <= 1 || n > MaxN) || (m <= 0 || m > MaxM)) {
return 1;
}
for(i = 0; i < m; i++) {
scanf("%d %d %d", &xi, &yi, &vi);
if((xi < 1 || xi > n) || (yi < 1 || yi > n) || vi <= 0) {
return 1;
}
roads[i].xi = xi;
roads[i].yi = yi;
roads[i].vi = vi;
}
scanf("%d %d", &s, &t);
if((s < 1 || s > n) || (t < 1 || t > n) || (s == t)) {
return 1;
}
//排序道路
sort(m);
ans = MaxANS;
//搜索所有道路
for(i = 0; i < m; i++){
//初始化并查集
for(j = 1; j <= n; j++) {
set[j] = j;
}
//设置当前最小速度
min = roads[i].vi;
//遍历道路,合并景点
for(j = i; j < m; j++) {
//更新当前最大速度
max = roads[j].vi;
//合并相连景点
union_set(roads[j].xi, roads[j].yi);
//如果起始点s和目标点t已联通,结束搜索
if(find(s) == find(t)) {
//更新最舒适结果
if((max * 1.0) / (min * 1.0) < ans) {
ans = (max * 1.0) / (min * 1.0);
ansmin = min;
ansmax = max;
}
break;
}
}
}
//检查是否有最舒适路径
if(ans == MaxANS) {
printf("IMPOSSIBLE");
}
else {
//最终值是整数
if(ansmax % ansmin == 0) {
printf("%d", ansmax / ansmin);
}
else {
printf("%d/%d", ansmax/gcd(ansmax, ansmin), ansmin/gcd(ansmax, ansmin));
}
}
return 0;
}