题意:
给了一个无向图,给了S和T两个点,问从S走到T的路径中,最大值比最小值 的 最小是多少
思路:
点只有500个,边只有5000个,所以支持O(m^2)
判断S到T的话,我们可以用并查集维护联通性。
类似最小生成树,对边权从小到大排序。
枚举第一条边,然后对边一条条加进去,直到S能走到T时即可,这时候判断比值是否小于当前答案,把除法变成乘法,防止丢失精度。
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+50;
struct edge{
int x,y,v;
}e[N];
int f[N];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
int main(){
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y,z;cin>>x>>y>>z;
e[i]={x,y,z};
}
sort(e+1,e+m+1,[](edge a,edge b){
return a.v<b.v;
});
int S,T;cin>>S>>T;
int fz=30000,fm=1;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++) f[j]=j;
int ma=-1,mi=30000;
for(int j=i;j<=m;j++){
int fx=find(e[j].x);
int fy=find(e[j].y);
if(fx!=fy){
f[fx]=fy;
ma=max(ma,e[j].v);
mi=min(mi,e[j].v);
if(find(S)==find(T)){
if(fz*mi>fm*ma){
int g=__gcd(ma,mi);
fz=ma/g,fm=mi/g;
}
break;
}
}
}
}
if(fz==30000) cout<<"IMPOSSIBLE";
else {
cout<<fz;
if(fm!=1) cout<<"/"<<fm;
}
return 0;
} 
京公网安备 11010502036488号