传送门biu~
将边排序,枚举最小边,用类似Kruskal的方法加边横并点集,当S和T属于一个集合时,最后加入的边一定是最大边。
#include<bits/stdc++.h>
using namespace std;
int n,m,ansA=-1,ansB,s,t;
int father[505];
struct edge{int x,y,len;}a[5005];
bool cmp(edge a,edge b){return a.len<b.len;}
int search(int x){return father[x]==x?x:father[x]=search(father[x]);}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].len);
scanf("%d%d",&s,&t);
sort(a+1,a+m+1,cmp);
for(int i=1;i<=m;++i){
for(int j=1;j<=n;++j) father[j]=j;
int A=-1,B=a[i].len;
father[a[i].x]=a[i].y;
if(search(s)==search(t)){
printf("1");
return 0;
}
for(int j=i+1;j<=m;++j){
int xn=search(a[j].x);
int yn=search(a[j].y);
if(xn!=yn) father[xn]=yn;
if(search(s)==search(t)){
A=a[j].len;
break;
}
}
if(A!=-1 && (ansA==-1 || A*ansB<ansA*B)){
ansA=A;
ansB=B;
int g=__gcd(ansA,ansB);
ansA/=g;ansB/=g;
}
}
if(ansA==-1)
printf("IMPOSSIBLE");
else if(ansB==1)
printf("%d",ansA);
else
printf("%d/%d",ansA,ansB);
return 0;
}