您的位置:首页 > 其它

DGZX1524 - 旅行

2013-12-19 20:10 169 查看
当给出的数据无序的时候,不妨考虑先排序,排序以后或许能发现规律。本题正是要先对数据进行排序,不妨把所有公路按行驶速度从小到大排序。

本题求最小速度比,由路径上的最大速度和最小速度决定。涉及两个要素的时候,不妨尝试通过枚举使一个要素固定下来。比如这道题,可以枚举最小速度。

假如排序以后8条边如下:1 2 3 4 5 6 7 8

先考虑最小速度取1的时候,最大速度取多少呢?2还是3?还是4?怎么找到最大速度呢?不难想到,只要把这些边从小到大依次加入,当加入某一条边的时候,出发点和目的地连通了,那最大速度就是这条边的权值。后面的边肯定不需要考虑了。

然后再考虑最小速度取其他值的情况,如法炮制。

原来这题就是考察并查集。

#include <stdio.h>

const int inf=123456789;
struct EDGE
{
int x, y, l;
};
EDGE a[5001];
int f[501];
int s, t, n, m, amax, amin;
double ans;

void init()
{
scanf("%d%d", &n, &m);
for (int i=1; i<=m; i++)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].l);
scanf("%d%d", &s, &t);
}

int get(int x)
{
int root = x;
while (f[root]!=root) root = f[root];
int p = x;
while (f[p]!=p)
{
p = f[p];
f[x] = root;
x = p;
}
return root;
}

int gcd(int a, int b)
{
int k;
while (a%b!=0)
{
k = a;
a = b;
b = k % b;
}
return b;
}

void qsort(int s, int t)
{
int i, j, x;
EDGE y;
i = s;
j = t;
x = a[(i+j)>>1].l;
do
{
while (a[i].l<x) i++;
while (a[j].l>x) j--;
if (i<=j)
{
y = a[i];
a[i] = a[j];
a[j] = y;
i++; j--;
}
} while (i<=j);
if (i<t) qsort(i, t);
if (j>s) qsort(s, j);
}

void doit()
{
int i, j, k, fx, fy;
bool v;
qsort(1, m);
v = true;
ans = inf;
for (i=1; i<=m; i++)
{
for (j=1; j<=n; j++)
f[j] = j;
for (j=i; j<=m; j++)
{
fx = get(a[j].x);
fy = get(a[j].y);
if (fx!=fy) f[fx] = fy;
if (get(s)==get(t))// 找到从 s 到 t 的路径
{
if (a[j].l*1.0/a[i].l<ans)
{
ans = a[j].l*1.0 / a[i].l;
amax = a[j].l;
amin = a[i].l;
}
break;
}
}
if (get(s)!=get(t))
{
if (i==1)
v = false;
break;
}
}
if (!v) printf("IMPOSSIBLE\n");
else
{
k = gcd(amax, amin);
amax = amax / k;
amin = amin / k;
if (amax%amin==0) printf("%d\n", amax/amin);
else printf("%d/%d\n", amax, amin);
}
}

int main()
{
init();
doit();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: