思路
从最大边开始枚举,直到起点和终点连接为止,可以用并查集判断是否相连,(从最大枚举到最小、从次大枚举到最小…)这样一定能找到一个最小比值,5000的平方2.5e7。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N = 10005;
int t,n,m;
int p[505];
struct node
{
int u,v,w;
}e[10005];
int find(int x) // 并查集核心操作
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
bool cmp(node A,node B)
{
return A.w<B.w;
}
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
scanf("%d",&t);
while(t--)
{
double ans=1e9;
int maxv,minv;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
}
int s,t;
scanf("%d%d",&s,&t);
sort(e,e+m,cmp);
/*for(int i=0;i<m;i++)
{
printf("%d ",e[i].w);
}
puts("");*/
for(int k=m-1;k>=0;k--)
{
for(int i=1;i<=n;i++)
{
p[i]=i;
}
int i;
for(i=k;i>=0;i--)
{
int a=find(e[i].u);
int b=find(e[i].v);
if(a!=b) p[a]=b;
if(find(s)==find(t)) break;
}
if(i==-1) break;
if((e[k].w/(e[i].w*1.0))<ans)
{
ans=e[k].w/(e[i].w*1.0);
minv=e[i].w;
maxv=e[k].w;
//printf("%d %d\n",minv,maxv);
}
}
int cnt=gcd(minv,maxv);
//printf("%d %d %d\n",cnt,minv,maxv);
minv=minv/cnt;
maxv=maxv/cnt;
//printf("%d %d\n",minv,maxv);
if(ans==1e9) printf("IMPOSSIBLE\n");
else if(maxv % minv == 0) printf("%d\n", maxv / minv);
else printf("%d/%d\n",maxv, minv);
}
return 0;
}