Description
Input
Subsequent test cases are separated with a single blank line.
Output
Sample Input
Sample Output
5
这道题意思真难懂,首先输入数据,第一行两个数分别表示消防站和十字路口的个数,
第二行表示消防站所在的路口,接下来若干行表示每个十字路口的相连和长度,最后
输入会有一个空行结束(坑死在这里了),找到每个十字路口距离最近的消防站,求出
在最小坐标建立消防站使得最远距离最小。
可以先求出每个消防站到每个点的距离,统计每个点的最小值就是各点到消防站的最
短路,统计一个最大就是得到距离消防站最远距离是多少了,然后对每个没有处理
的十字路口进行假设此处有一个消防站,求出距离最近的消防站的最大距离是否比
开始求出的最大值小,如果小那么此点设一个消防站就更优一些。
#include <stdio.h> #include <vector> #include <queue> #include <string.h> #define INF 0x3f3f3f3f using namespace std; const int maxn = 505; int f[maxn], dis[maxn], m, ans[maxn]; bool vis[maxn]; char str[maxn]; struct node { int v, len; } t; vector < node > mp[maxn]; queue < int > q; void init ( ) { for ( int i = 0; i <= m; i ++ ) mp[i].clear ( ); memset ( ans, 0x3f, sizeof ( ans ) ); memset ( f, 0, sizeof ( f ) ); } inline int Max ( int a, int b ) { return a > b ? a : b; } inline int Min ( int a, int b ) { return a < b ? a : b; } void spfa ( int s ) //求单源最短路 { for ( int i = 1; i <= m; i ++ ) vis[i] = false, dis[i] = INF; while ( ! q.empty ( ) ) q.pop ( ); dis[s] = 0; q.push ( s ); while ( ! q.empty ( ) ) { int u = q.front ( ); q.pop ( ); vis[u] = false; for ( int i = 0; i < mp[u].size ( ); i ++ ) { t = mp[u][i]; if ( t.len+dis[u] < dis[t.v] ) { dis[t.v] = t.len+dis[u]; //更新s-v的最短路 if ( vis[t.v] == false ) //没有进队列 { vis[t.v] = true; q.push ( t.v ); } } } } } void print ( ) { for ( int i = 1; i <= m; i ++ ) printf ( "%d ", dis[i] ); printf ( "\n" ); } int main ( ) { int n, x, u, v, l, res, id; while ( ~ scanf ( "%d%d", &n, &m ) ) { init ( ); for ( int i = 0; i < n; i ++ ) { scanf ( "%d", &x ); f[x] = 1; } getchar ( ); while ( gets ( str ) && strlen ( str ) ) //注意这里是多组,不是m组 { sscanf ( str, "%d%d%d", &u, &v, &l ); t.v = v, t.len = l; mp[u].push_back ( t ); t.v = u; mp[v].push_back ( t ); } for ( int i = 1; i <= m; i ++ ) { if ( f[i] ) //求出每个消防站到每个十字路口的距离 { spfa ( i ); for ( int j = 1; j <= m; j ++ ) //找每个十字路径距离最近的消防站 ans[j] = Min ( ans[j], dis[j] ); //print ( ); } } res = 0; for ( int i = 1; i <= m; i ++ ) //找距离最远 res = Max ( res, ans[i] ); id = 1; for ( int i = 1; i <= m; i ++ ) { if ( f[i] == 0 ) //对每个没求过的十字路口假设设定一个消防站,求出最优值 { spfa ( i ); int mx = 0; for ( int j = 1; j <= m; j ++ ) //找距离最近的最大值 mx = Max ( mx, Min ( ans[j], dis[j] ) ); if ( mx < res ) //res大于mx证明在i这个位置更优一些 { res = mx; id = i; } } } printf ( "%d\n", id ); } return 0; }