这道题。。。一眼看出一个暴力思虑。。。那就是按照生成树。。。
排完序之后从当前边开始向后做生成树。。。
统计一下答案就好了。。。
结果。。。这就是正解。。。QVQ。。。smg。。。我去。。。
呆码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<algorithm> #define INF 99999999 #define MAXN 1010 #define unionn(x,y) fa[y]=x #define eps 0.000001 using namespace std; int fa[MAXN],n,m,s,t,maxn,minx,ll=INF,rr=INF; double ans=999999; struct asd{ int x,y,v; } r[20010]; inline int find(int x) { if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } inline bool cmp(asd x,asd y) { return x.v<y.v; } inline int gcd(int a,int b) { return b==0 ? a : gcd(b,a%b); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&r[i].x,&r[i].y,&r[i].v); scanf("%d%d",&s,&t); sort(r+1,r+1+m,cmp); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) fa[j]=j; unionn(find(r[i].x),find(r[i].y)); minx=maxn=r[i].v; if(find(s)==find(t)) { double anss=ans; ans=(double)maxn/minx; if(ans-eps<anss-eps) ll=maxn,rr=minx; break; } for(int j=i+1;j<=m;j++) if(find(r[j].x)!=find(r[j].y)) { unionn(find(r[j].x),find(r[j].y)); minx=min(minx,r[j].v); maxn=max(maxn,r[j].v); if(find(s)==find(t)) { double anss=ans; ans=(double)maxn/minx; if(ans-eps<anss-eps) ll=maxn,rr=minx; else ans=anss; break; } } } if(ll==INF) { printf("IMPOSSIBLE "); return 0;} if((double)ll/rr==ll/rr) printf("%d",ll/rr); else { while(gcd(rr,ll)!=1) { int mid=gcd(rr,ll); ll/=mid; rr/=mid; } printf("%d/%d ",ll,rr); } }
不过细节比较多。。。要注意。。。