不错的题,lyp去年培训讲过,首先排一遍序,然后从小到大枚举每一条边,以这条边为最小边向后枚举,直到s和t联通,没了。。。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 10010
using namespace std;
struct yts
{
int x,y,w;
}e[maxn];
int n,m,s,t,ans1,ans2;
int f[maxn];
bool cmp(yts x,yts y)
{
return x.w<y.w;
}
int find(int x)
{
if (f[x]==x) return x;
else return f[x]=find(f[x]);
}
int gcd(int a,int b)
{
if (b==0) return a;
else return gcd(b,a%b);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
scanf("%d%d",&s,&t);
sort(e+1,e+m+1,cmp);
ans1=60000;ans2=1;
for (int i=1;i<=m;i++)
{
for (int j=1;j<=n;j++) f[j]=j;
int j;
bool w=0;
for (j=i;j<=m;j++)
{
int f1=find(e[j].x),f2=find(e[j].y);
if (f1!=f2) f[f1]=f2;
if (find(s)==find(t)) {w=1;break;}
}
if (w && e[j].w*ans2<ans1*e[i].w) ans1=e[j].w,ans2=e[i].w;
}
int GCD=gcd(ans1,ans2);
ans1/=GCD;ans2/=GCD;
if (ans1==60000) printf("IMPOSSIBLE\n");
else if (ans2==1) printf("%d\n",ans1);
else printf("%d/%d\n",ans1,ans2);
return 0;
}