例题11-5 噪音恐惧症 UVa10048

1.题目描述:点击打开链接

2.解题思路:本题的解题过程类似于Floyd算法的原理,即:任意一条至少包含两条边的路径,一定存在一个中间点k,使得d(i,j)=d(i,k)+d(k,j),其中d(i,j)表示(i,j)的最短长度,对于不同的点k,d(i,k)+d(k,j)可能不相同,因此最后要取最小值。对于本题,即max(d[i][k],d[k][j])可能不同,因此最后要取最小值。所以,只需要把Floyd算法的最后一句修改为d[i][j]=min{d[i][j],max(d[i][k],d[k][j])}即可。

3.代码:

#define _CRT_SECURE_NO_WARNINGS 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define N 1000+10
#define INF 100000000
int d[N][N];
int c,s,q;

int main()
{
	freopen("t.txt", "r", stdin);
	int rnd = 0;
	while (cin >> c >> s >> q&&(c||s||q))
	{
		int c1, c2, del;
		for (int i = 0; i < N;i++)
		for (int j = 0; j < N; j++)
			d[i][j] = INF;
		for (int i = 0; i < s; i++)
		{
			cin >> c1 >> c2 >> del;
			d[c1][c2] = del;
			d[c2][c1] = del;
		}
		for (int k = 1; k <= c;k++)
		for (int i = 1; i <= c;i++)
		for (int j = 1; j <= c;j++)
			d[i][j] = min(d[i][j], max(d[i][k], d[k][j]));
		if (rnd)cout << endl;
		printf("Case #%d\n", ++rnd);
		while (q--)
		{
			int u, v;
			cin >> u >> v;
			if (d[u][v] < INF)cout << d[u][v] << endl;
			else puts("no path");
		}
	}
	return 0;
}

你可能感兴趣的:(算法竞赛入门经典(第二版),图论——最短路)