【SSL】1312旅行

【SSL】1312旅行

Time Limit:3000MS
Memory Limit:65536K

Description

Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。Z小镇附近共有N个景点(编号为1,2,3,…,N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。速度变化太快使得游客们很不舒服,因此从一个景点前往另一个景点的时候,大家都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。

Input

第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。
最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。

Output

如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。

Sample Input

样例1

4 2
1 2 1
3 4 2
1 4

样例2

3 3
1 2 10
1 2 5
2 3 8
1 3

样例3

3 2
1 2 2
2 3 4
1 3

Sample Output

样例1

IMPOSSIBLE

样例2

5/4

样例3

2

Hint

【数据范围】
1<N<=500
1<=x,y<=N,0<v<30000,x≠y
0<M<=5000

思路

把边排序一遍,然后枚举起始边,并查集连续,直到两个点先连为止。然后求最大速度和最小速度的最小比。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,f[5010];
int s,t,ansmx,ansmn;
double mn=1000000000;
struct jgt
{
    
    
	int x,y,v;
}a[5010]; 
void makenull()//初始化 
{
    
    
	for(int i=1;i<=n;f[i]=i,i++);
	return;
}
int find(int x)//找代表值 
{
    
    
	if(x==f[x])return x;
	return f[x]=find(f[x]);
}
void merge(int x,int y)//合并
{
    
    
	f[find(y)]=find(x);
	return;
}
bool connect(int x,int y)//判断同连通块 
{
    
    
	return (find(x)==find(y));
}
bool cmp(jgt t1,jgt t2)//用于排序 
{
    
    
	return t1.v<t2.v;
}
int gcd(int a,int b)//求最大公因数 
{
    
    
	int r;
	for(r=a%b;r;a=b,b=r,r=a%b);
	return b;
}
void input()//输入 
{
    
    
	int i;
	scanf("%d%d",&n,&m);
	for(i=0;i<m;i++)//合并 
		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);
	scanf("%d%d",&s,&t);
	return;
}
void work()
{
    
    
	int i,j;
	sort(a,a+m,cmp);
	for(i=0;i<m;i++)//枚举起始边 
	{
    
    
		makenull();
		for(j=i;j<m&&!connect(s,t);j++)
			merge(a[j].x,a[j].y);
		if(connect(s,t))
		{
    
    
			if(double(a[j-1].v)/double(a[i].v)<mn)//最小的速度比 
			{
    
    
				ansmx=a[j-1].v;
				ansmn=a[i].v;
				mn=double(a[j-1].v)/double(a[i].v);
			}
		}
	}
	return;
}
void output()//输出 
{
    
    
	int tem;
	if(mn==1000000000)
		printf("IMPOSSIBLE");
	else
		if(ansmx%ansmn==0) 
			printf("%d",ansmx/ansmn);
		else
		{
    
    
			tem=gcd(ansmx,ansmn);//约分 
			printf("%d/%d",ansmx/tem,ansmn/tem);
		}
	return;
}
int main()
{
    
    
	input();
	work();
	output();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46975572/article/details/112976618
SSL