枚举大法好。
先对边进行排序,然后枚举最大边,初始化并查集,依次加入更小的边,第一次连通时,更新答案,一轮枚举结束。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=1e9;
struct Edge{
int u,v,w;
bool operator<(const Edge& rhs)const{
return w>rhs.w;
}
}e[5005];
int pa[505],n,m;
int findset(int x){
return pa[x]!=x?findset(pa[x]):pa[x];
}
void init(){
for(int i=1;i<=n;i++)pa[i]=i;
}
int gcd(int a,int b){
return (!b)?a:gcd(b,a%b);
}
double divi(double a,double b){
return a/b;
}
int main(){
scanf("%d%d",&n,&m);
int s,t;
for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
scanf("%d%d",&s,&t);
sort(e+1,e+1+m);
int up=inf,down=1;
for(int i=1;i<=m;i++){
int a=e[i].w,b;
init();
for(int j=i;j<=m;j++){
b=e[j].w;
int u=findset(e[j].u),v=findset(e[j].v);
if(u!=v)pa[u]=v;
if(findset(s)==findset(t)){
if(divi(up,down)>divi(a,b)){
up=a;
down=b;
}
break;
}
}
}
int d=gcd(up,down);
up/=d;down/=d;
if(up>=inf)printf("IMPOSSIBLE");
else if(down==1)printf("%d",up);
else printf("%d/%d",up,down);
return 0;
}