2012-10-12 20:17:46Morris

[UVA][spfa] 10278 - Fire Station

Problem A: Fire Station

A city is served by a number of fire stations. Some residents have complained that the distance from their houses to the nearest station is too far, so a new station is to be built. You are to choose the location of the fire station so as to reduce the distance to the nearest station from the houses of the disgruntled residents.

The city has up to 500 intersections, connected by road segments of various lengths. No more than 20 road segments intersect at a given intersection. The location of houses and firestations alike are considered to be at intersections (the travel distance from the intersection to the actual building can be discounted). Furthermore, we assume that there is at least one house associated with every intersection. There may be more than one firestation per intersection.

The Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

The first line of input contains two positive integers: f,the number of existing fire stations (f <= 100) and i, the number of intersections (i <= 500). The intersections are numbered from 1 to i consecutively. f lines follow; each contains the intersection number at which an existing fire station is found. A number of lines follow, each containing three positive integers: the number of an intersection, the number of a different intersection, and the length of the road segment connecting the intersections. All road segments are two-way (at least as far as fire engines are concerned), and there will exist a route between any pair of intersections.

The Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

You are to output a single integer: the lowest intersection number at which a new fire station should be built so as to minimize the maximum distance from any intersection to the nearest fire station.

Sample Input

1

1 6
2
1 2 10
2 3 10
3 4 10
4 5 10
5 6 10
6 1 10

Output for Sample Input

5

先講解一下題目內容,平面上有 n 個點,其中 f 個點是消防站的位置,居民要到達消防站,現在請多設立一個消防站,使得這些居民到達消防站的最大值最小化。

很明顯地大部份人都使用 dijsktra, 但是在邊很少, 而且重複要對居民去找到最鄰近的消防站, 用 spfa 是比較好寫的, 而且效率比較好。

#include <stdio.h>
#include <queue>
#define oo 0xffffff
using namespace std;
int fire[505];
int g[505][505][2], gt[505];
int dist[505], f, n;
void spfa(int nd) {
int i, j, tn, mn;
char used[505] = {};
queue<int> Q;
for(i = 0; i <= n; i++)
used[i] = 0;
dist[nd] = 0;
Q.push(nd);
while(!Q.empty()) {
tn = Q.front();
Q.pop();
used[tn] = 0;
for(j = 0; j < gt[tn]; j++) {
if(dist[g[tn][j][0]] > dist[tn]+g[tn][j][1]) {
dist[g[tn][j][0]] = dist[tn]+g[tn][j][1];
if(!used[g[tn][j][0]])
Q.push(g[tn][j][0]), used[g[tn][j][0]] = 1;
}
}
}
}
int main() {
int t, i, j;
int a, b, c;
char in[505];
scanf("%d", &t);
while(t--) {
scanf("%d %d", &f, &n);
for(i = 0; i < f; i++)
scanf("%d", &fire[i]);
for(i = 0; i <= n; i++)
gt[i] = 0, dist[i] = oo;
gets(in);
while(gets(in)) {
if(!in[0]) break;
sscanf(in, "%d %d %d", &a, &b, &c);
g[a][gt[a]][0] = b, g[a][gt[a]++][1] = c;
g[b][gt[b]][0] = a, g[b][gt[b]++][1] = c;
}
for(i = 0; i < f; i++)
spfa(fire[i]);
int o[505];
for(i = 1; i <= n; i++)
o[i] = dist[i];
int ans = oo, anum;
for(i = 1; i <= n; i++) {
spfa(i);
int mx = -oo;
for(j = 1; j <= n; j++) {
if(mx < dist[j])
mx = dist[j];
}
if(ans > mx) ans = mx, anum = i;
for(j = 1; j <= n; j++)
dist[j] = o[j];
}
printf("%d\n", anum);
if(t) puts("");
}
return 0;
}