枚举大法好。
先对边进行排序,然后枚举最大边,初始化并查集,依次加入更小的边,第一次连通时,更新答案,一轮枚举结束。
#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; }