题意:
给了一个无向图,给了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; }