最舒适的路线
时间限制:5000 ms | 内存限制:65535 KB
难度:5
描述
异形卵潜伏在某区域的一个神经网络中。其网络共有N个神经元(编号为1,2,3,…,N),这些神经元由M条通道连接着。两个神经元之间可能有多条通道。异形卵可以在这些通道上来回游动,但在神经网络中任一条通道的游动速度必须是一定的。当然异形卵不希望从一条通道游动到另一条通道速度变化太大,否则它会很不舒服。
现在异形卵聚居在神经元S点,想游动到神经元T点。它希望选择一条游动过程中通道最大速度与最小速度比尽可能小的路线,也就是所谓最舒适的路线。
输入
第一行: K 表示有多少组测试数据。
接下来对每组测试数据:
第1行: N M
第2~M+1行: Xi Yi Vi (i=1,…..,M)
表示神经元Xi 到神经元Yi之间通道的速度必须是Vi
最后一行: S T ( S ¹ T )
【约束条件】
2≤K≤5 1<N≤500 0<M≤5000 1≤ Xi, Yi , S , T ≤N 0< Vi <30000,
Vi是整数。数据之间有一个空格。
输出
对于每组测试数据,输出一行:如果神经元S到神经元T没有路线,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
样例输入
2
3 2
1 2 2
2 3 4
1 3
3 3
1 2 10
1 2 5
2 3 8
1 3
样例输出
2
5/4
#include<stdio.h>
#include<algorithm>
#define INF 0x3fffffff
using namespace std;
const int N = 5005;
struct edge
{
int x;
int y;
int v;
}e[N];
int father[N];
void Init(int n)//初始化
{
for(int i = 1; i <= n; i++)
father[i] = i;
}
bool comp(edge e1, edge e2)
{
return e1.v > e2.v;
}
int Find(int x)//查找
{
if(x != father[x])
father[x] = Find(father[x]);
return father[x];
}
void Union(int a, int b)//合并
{
int p = Find(a);
int q = Find(b);
if(p > q)
father[p] = q;
else
father[q] = p;
}
int gcd(int a, int b)//最大公约数
{
while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
return a;
}
int main()
{
int T, n, m, i, j, s, t, aa, bb;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i = 0; i < m; i++)
scanf("%d%d%d",&e[i].x, &e[i].y, &e[i].v);
scanf("%d%d",&s,&t);
sort(e, e+m, comp);
double rate = INF*1.0;
for(i = 0; i < m; i++) //枚举速度最大的边
{
Init(n);
for(j = i; j < m; j++) //查找使S到达T的最大速度
{
if(Find(e[j].x) != Find(e[j].y))
Union(e[j].x, e[j].y);
if(Find(s) == Find(t))
break;
}
if(j == m) break;
int v1 = e[i].v, v2 = e[j].v;
if(v1*1.0 / v2 < rate) //比原来的比值小
{
aa = v1, bb = v2; //记录最大速度和最小速度
rate = v1*1.0 / v2; //更新最小比值
}
}
if(rate == INF)
printf("IMPOSSIBLE\n");
else if(aa % bb == 0)
printf("%d\n",aa/bb);
else
printf("%d/%d\n",aa/gcd(aa,bb), bb/gcd(aa,bb));
}
return 0;
}