標籤:最短路 spfa
枚舉+最短路問題。
題意依然晦澀難懂。
建立一個消防站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 longusing 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); }}
POJ 2607 Fire Station