DGZX1524 - 旅行

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

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

假如排序以后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;
}

 

posted @ 2013-12-19 20:10  莞中OI  阅读(257)  评论(0)    收藏  举报