枚举+最短路问题。
题意依然晦涩难懂。
新建一个消防站n 可以使得所有交叉路口到最近的一个消防站的距离中最大值减小,且n 是满足条件的交叉路口序号中序号最小的。
先每个消防站做SPFA。找到所有点 到最近消防站的 距离。
然后枚举 每个不是消防站的点,找到距离这个点的最大距离。然后比对 最大是否更新了。
ORZ的是,输入边的时候要EOF。简直……
谁是出题人,看我不把他脸按到键OWIHW#ROIJHA(P*#RY(#*Y(*#@UISHIUOHEOIF
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<stack>
#include<iostream>
#include<list>
#include<set>
#include<cmath>
#define INF 0x7fffffff
#define eps 1e-6
#define LL long long
using namespace std;
struct lx
{
int v,len;
};
vector<lx>g[501];
int n,m;
bool thend[501];
int d[501];
void SPFA(int start,int *dis)
{
queue<int>q;
bool vis[501];
for(int i=1;i<=n;i++)
vis[i]=0;
dis[start]=0;
vis[start]=1;
q.push(start);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int j=0; j<g[u].size(); j++)
{
int v=g[u][j].v;
int len=g[u][j].len;
if(dis[v]>dis[u]+len)
{
dis[v]=dis[u]+len;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
for(int i=1; i<=n; i++)
thend[i]=0,g[i].clear();
for(int i=1; i<=m; i++)
{
int tmp;
scanf("%d",&tmp);
thend[tmp]=1;
}
int u,v,len;
while(scanf("%d%d%d",&u,&v,&len)!=EOF)
{
lx now;
now.len=len;
now.v=v,g[u].push_back(now);
now.v=u,g[v].push_back(now);
}
for(int i=1;i<=n;i++)
d[i]=INF;
for(int i=1;i<=n;i++)
if(thend[i])
{
SPFA(i,d);
}
int minn=INF;
int ans=1;
for(int i=1;i<=n;i++)
{
int maxn=0;
if(thend[i])continue;
int dis[501];
for(int j=1;j<=n;j++)
dis[j]=d[j];
SPFA(i,dis);
for(int j=1;j<=n;j++)
maxn=max(maxn,dis[j]);
if(minn>maxn)
{
minn=maxn;
ans=i;
}
}
printf("%d\n",ans);
}
}