枚举+最短路问题。
题意依然晦涩难懂。
新建一个消防站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); } }
原文:http://blog.csdn.net/dongshimou/article/details/38015363