1050: [HAOI2006]旅行comf
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2907 Solved: 1591
[ Submit][ Status][ Discuss]
Description
给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T
,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出
这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。
Input
第一行包含两个正整数,N和M。下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向
公路,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速
度比最小的路径。s和t不可能相同。
1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000
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
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
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2
HINT
题目大意:
如题。
思路:
题意总结上写的这个是并查集 不过看过题目后并不怎么觉得和并查集有什么关系。 后来想起来,可以用并查集判断两个点是否连通。
那么我们按照权值从小到大进行排序,开始枚举。
枚举最小的权值,然后按照顺序加入边构建这个图 一直到两个点连通,那么此时最后一个加进来的权值就刚好是 最小的最大权值。
AC代码:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int u;
int v;
int cost;
friend bool operator < (const node &a,const node &b)
{
return a.cost<b.cost;
}
}aa[5005];
int gcd(int u,int v)
{
if(u%v==0)
return v;
return gcd(v,u%v);
}
int parent[505];
int n,m;
int ss,ee;
int GetParent(int a)
{
if( parent[a]!= a)
parent[a] = GetParent(parent[a]);
return parent[a];
}
void Merge(int a,int b)
{
int p1 = GetParent(a);
int p2 = GetParent(b);
if( p1 == p2 )
return;
parent[p2] = p1;
}
void hehe()
{
for(int i=0;i<=n;i++)
{
parent[i]=i;
}
}
int main()
{
scanf("%d%d",&n,&m);
long double minn=99999999;
long double temp;
int son;
int mother;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&aa[i].u,&aa[i].v,&aa[i].cost);
}
scanf("%d%d",&ss,&ee);
sort(aa,aa+m);
for(int i=0;i<m;i++)
{
hehe();
for(int j=i;j<m;j++)
{
Merge(aa[j].u,aa[j].v);
if(GetParent(ss)==GetParent(ee))
{
temp=(long double)aa[j].cost/(long double)aa[i].cost;
if(minn>temp)
{
minn=temp;
son=aa[j].cost;
mother=aa[i].cost;
}
break;
}
}
}
if(minn==99999999)
{
cout<<"IMPOSSIBLE"<<endl;
}
else
{
int tt=gcd(son,mother);
son/=tt;
mother/=tt;
if(mother==1)
{
cout<<son<<endl;
}
else
{
cout<<son<<"/"<<mother<<endl;
}
}
}