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;
	}
posted @ 2018-09-04 20:36  Tony_Double_Sky  阅读(130)  评论(0编辑  收藏  举报