poj 2607 Fire Station

来源:互联网 发布:nginx 网站根目录 编辑:程序博客网 时间:2024/05/22 01:49

题目描述:某个城市的消防任务由一些消防站承担。有些居民抱怨离他们家最近的消防站距离太远了,所以市政府决定在修建一个新的消防站。试选择消防站的位置,以减小这些居民离家最近的消防站的距离。


思路:其实这题是一个最短路径的枚举,用dist[i]表示i号路口距离最近的消防站的距离,先求出已经存在的消防站的最短路径,更新dist数组,然后枚举剩下的路口,更新dist求出最小值。此题可以用floyd先求出所有的最短路径,然后再去更新比较,不过效率不高用时1797ms。用优化的spfa只需79ms.


floyd代码:

#include <iostream>#include <algorithm>#include <cstdio>using namespace std;const int inf = 1000000000;const int maxn = 505;int f,n;bool sta[maxn];//消防站 int edge[maxn][maxn];int dist[maxn];bool input(){if(scanf("%d%d",&f,&n) != 2) return false;int x;for(int i = 1; i <= n; i++) sta[i] = false;for(int i = 0; i < f; i++){scanf("%d",&x);sta[x] = true;}for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){if(i == j) edge[i][j] = 0;else edge[i][j] = inf;}}int u,v,w;while(scanf("%d%d%d",&u,&v,&w) == 3){edge[u][v] = edge[v][u] = w;}return true;}void floyd(){for(int k = 1; k <= n; k++){for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){edge[i][j] = min(edge[i][j],edge[i][k]+edge[k][j]);}}}}void solve(){floyd();for(int i = 1; i <= n; i++) dist[i] = inf;//用已存在的消防站来确定每个路口离消防站的距离 for(int i = 1; i <= n; i++){if(!sta[i]) continue;for(int j = 1; j <= n; j++){dist[j] = min(dist[j],edge[i][j]);}}int index = 1;int minimum = inf;int t_dist[maxn];//放置消防站 for(int i = 1; i <= n; i++){if(sta[i]) continue;int maximum = -inf;for(int j = 1; j <= n; j++) t_dist[j] = dist[j];for(int j = 1; j <= n; j++){t_dist[j] = min(t_dist[j],edge[i][j]);maximum = max(t_dist[j],maximum);}if(maximum < minimum){minimum = maximum;index = i;}}printf("%d\n",index);}int main(){while(input()){solve();}return 0;}

spfa代码:

#include <iostream>#include <algorithm>#include <cstdio>#include <queue>using namespace std;const int inf = 1000000000;const int maxn = 505;struct node{int v,w;node(int _v, int _w){v = _v, w = _w;}};int f,n;bool sta[maxn];//消防站 vector<node> list[maxn];int dist[maxn];bool inq[maxn];bool input(){if(scanf("%d%d",&f,&n) != 2) return false;int x;for(int i = 1; i <= n; i++) sta[i] = false;for(int i = 0; i < f; i++){scanf("%d",&x);sta[x] = true;}for(int i = 1; i <= n; i++) list[i].clear();int u,v,w;while(scanf("%d%d%d",&u,&v,&w) == 3){list[u].push_back(node(v,w));list[v].push_back(node(u,w));}return true;}void spfa(int s, int *d){queue<int> q;for(int i = 1; i <= n; i++){inq[i] = false;}d[s] = 0;q.push(s);while(!q.empty()){int u = q.front(); q.pop(); inq[u] = false;for(int i = 0; i < list[u].size(); i++){int v = list[u][i].v;int w = list[u][i].w;if(d[u] + w < d[v]){d[v] = d[u] + w;if(!inq[v]){q.push(v);inq[v] = true;}}}}}void solve(){for(int i = 1; i <= n; i++) dist[i] = inf;for(int i  = 1; i <= n; i++){if(sta[i]){spfa(i,dist);}}int index = 1;int minimum = inf;int t_dist[maxn];//放置消防站 for(int i = 1; i <= n; i++){if(sta[i]) continue;int maximum = -inf;for(int j = 1; j <= n; j++) t_dist[j] = dist[j];spfa(i,t_dist);for(int j = 1; j <= n; j++) maximum = max(maximum,t_dist[j]);if(maximum < minimum){minimum = maximum;index = i;}}printf("%d\n",index);}int main(){while(input()){solve();}return 0;}


0 0
原创粉丝点击