用并查集,枚举下界,可以参考HDU1598题。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
#define INF 30000
#define MAXN 500+10
#define N 5000+10
int f[MAXN];
struct PATH
{
int x;
int y;
int v;
}d[N];
int cmp(const void *a,const void *b)
{
return (*(PATH *)a).v - (*(PATH *)b).v;
}
int common(int m,int n)
{
int t,i;
if(m < n)
{ t = m; m = n; n = t;}
for(i = n; i > 0; i--)
if(m%i == 0&&n%i == 0)
return i;
}
int getfather(int x)
{
if(x != f[x])
f[x] = getfather(f[x]);
return f[x];
}
int Union(int x,int y)
{
int fx = getfather(x);
int fy = getfather(y);
if(fx != fy)
f[fx] = fy;
return 0;
}
int main()
{
//freopen("test.txt","r",stdin);
int max,min,cmn,from,to,x,y,v,k,n,m,i,j;
double rate;
scanf("%d",&k);
while(k--)
{
max = -INF;
min = INF;
rate = INF*1.0;
scanf("%d%d",&n,&m);
//for(i = 1; i <= n; i++)
//f[i] = i;
for(i = 0; i < m; i++)
scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].v);
qsort(d,m,sizeof(PATH),cmp);
scanf("%d%d",&from,&to);
for(i = 0; i < m; i++)
{
for(j = 1; j <= n; j++)
f[j] = j;
for(j = i; j < m; j++)
{
Union(d[j].x,d[j].y);
if(getfather(from) == getfather(to))
break;
}
if(j < m)
{
double r = (d[j].v*1.0)/(d[i].v*1.0);
if(r < rate)
{
rate = r;
max = d[j].v;
min = d[i].v;
}
}
}
if(rate == INF*1.0)
printf("IMPOSSIBLE\n");
else
{
if(max%min == 0)
printf("%d\n",max/min);
else
{
cmn = common(max,min);
printf("%d/%d\n",max/cmn,min/cmn);
}
}
}
return 0;
}