poj 2607

城市要新建一个消防站,减少居民离最近的消费站之间的距离。

输入文本,第一行有两个正整数f,i。f表示消防站的数目,i表示交叉路口的数目。接下来给出f行,每行给出一个消防站的路口序号,接下来有若干行,每行有3个正整数,格式为A,B,L,A B表示路口,L表示路段的长度。道路是双向的。

对于每组数据输出一个n,n的含义是新的消防站所在的交叉路口的序号,选择n可以使得所有交叉路口到最近的一个消防站的距离中的最大值最小,而且n是满足条件的交叉路口序号中序号最小的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;


const int inf=9999999;
const int MAXN=505;
int maze[MAXN][MAXN];
bool house[MAXN];
int dis[MAXN],fire,n;


int main(){
    int u,v,w; 
    while(scanf("%d%d",&fire,&n)!=EOF){
        memset(house,false,sizeof(house));
        for(int i=1;i<MAXN;i++){ 
            maze[i][i]=0; dis[i]=inf;
            for(int j=i+1;j<MAXN;j++)
            maze[i][j]=maze[j][i]=inf;
        }
        int station;
        for(int i=0;i<fire;i++){
            scanf("%d",&station);
            house[station]=true;
            dis[station]=0;
        }
        while(~scanf("%d%d%d",&u,&v,&w)){
            maze[u][v]=maze[v][u]=min(w,maze[u][v]);
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(maze[i][k]+maze[k][j]<maze[i][j]){
                        maze[i][j]=maze[i][k]+maze[k][j];
                    }
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(house[j])
                dis[i]=min(dis[i],maze[i][j]);
            }
        }


        int tmp,ans,s=inf;
        for(int i=1;i<=n;i++){
            tmp=0;
            for(int j=1;j<=n;j++){
                tmp=max(min(dis[j],maze[i][j]),tmp);
            }
            if(tmp<s){
                s=tmp; ans=i; 
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
点赞