枚举+并查集可过。
从最小的边开始枚举,知道s,p相联通,记录最小值比较
算是生成树 并查集稍难的应用吧
然而我太菜写跪了两天 码力不足啊 QAQ
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
const int N=5020;
int n,r,m,t,inde,flag;
int fg,cnt,scnt,q,e,s,p,k1,k2,maxx,minn;
int fa[N];
double ans;
bool fl;
struct Edge{
int w,f,to;
}a[N];
int cmp(Edge x,Edge y){
return x.w<y.w;
}
int find(int x){
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
int gcd(int a,int b){
if (!b) return a;
else return gcd(b,a%b);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
cin>>q>>e>>r;
int f1=find(q),f2=find(e);
if (f1!=f2) fa[f1]=f2;
a[i].f=q,a[i].to=e,a[i].w=r;
}
cin>>s>>p;
if(find(s)!=find(p)) {
cout<<"IMPOSSIBLE"; return 0;
}
ans=3000000;
sort(a,a+m+1,cmp);
for(int i=1;i<=m;i++){
fl=0; int c;
for(int j=1;j<=n;j++) fa[j]=j;
for(int j=i;j<=m;j++){
int f1=find(a[j].f),f2=find(a[j].to);
if (f1!=f2) fa[f1]=f2;
if (find(s)==find(p)){
c=j;
fl=true;
break;
}
}
if (fl)
{
double now=(a[c].w+0.0)/(a[i].w+0.0);
// cout<<now<<"dd"<<a[c].w<<a[i].w<<endl;
if (now<ans) ans=now,k1=a[c].w,k2=a[i].w;
}
}
if(k1%k2==0) cout<<k1/k2;
else {
int v=gcd(k1,k2);
cout<<k1/v <<"/"<<k2/v;
}
// cout<<k1<<k2;
return 0;
}