poj 2607 Fire Station(floyd)

Fire Station
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 3680 Accepted: 1303

Description

A city is served by a number of fire stations. Some residents have complained that the distance from their houses to the nearest station is too far, so a new station is to be built. You are to choose the location of the fire station so as to reduce the distance to the nearest station from the houses of the disgruntled residents. 
The city has up to 500 intersections, connected by road segments of various lengths. No more than 20 road segments intersect at a given intersection. The location of houses and firestations alike are considered to be at intersections (the travel distance from the intersection to the actual building can be discounted). Furthermore, we assume that there is at least one house associated with every intersection. There may be more than one firestation per intersection. 

Input

The first line of input contains two positive integers: f,the number of existing fire stations (f <= 100) and i, the number of intersections (i <= 500). The intersections are numbered from 1 to i consecutively. f lines follow; each contains the intersection number at which an existing fire station is found. A number of lines follow, each containing three positive integers: the number of an intersection, the number of a different intersection, and the length of the road segment connecting the intersections. All road segments are two-way (at least as far as fire engines are concerned), and there will exist a route between any pair of intersections.

Output

You are to output a single integer: the lowest intersection number at which a new fire station should be built so as to minimize the maximum distance from any intersection to the nearest fire station.

Sample Input

1 6
2
1 2 10
2 3 10
3 4 10
4 5 10
5 6 10
6 1 10

Sample Output

5

Source

Waterloo local 1999.09.25

题意:在一个n各节点的城市,拥有f座消防站,一些居民因为消防站离他们太远而不满,政府决定新建一座消防站,使距离消防站距离最远居民点尽可能近,同时多个点满足时取最小编号的那个。

思路:flloyd计算出在已有f个消防站情况下,每个居民点离附近最近的消防站距离,再一一枚举各个居民点成为消防站。每次枚举时,收缩其他居民点距消防站最近距离,统计距离最大的,若比没建时要近的话,满足题意,更新ansid。

此题有坑点,若图已建满消防站,根据题意,仍需在节点1新建一座,注意。

代码(据说此题在不同oj数据不同,楼主AC在poj,820ms):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN=505;
int g[MAXN][MAXN],ming[MAXN],da[MAXN],db[MAXN],in[MAXN];
int tmp[MAXN][MAXN];
void floyd(int n)
{
    int k,i,j;
    for(k=1;k<=n;k++)
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
int main()
{
    int f,n,m,a,b,c,i,j;char sss[100];
    while(~scanf("%d%d",&f,&n))
    {
        memset(in,0,sizeof in);
        for(i=0;i<f;i++)//将消防站节点存在da【】
        {
            scanf("%d",&da[i]);
            in[da[i]]=1;
        }
        getchar();
        int ff=0;
        for(i=1;i<=n;i++)//将居民点节点存进db【】
        {
            if(!in[i])db[ff++]=i;
        }
        if(ff==0)//特判.若图已建满,输出 1
        {
            printf("%d\n",1);
            continue;
        }
        memset(g,INF,sizeof g);
        for(i=1;i<=n;i++)
            g[i][i]=0;
        while(gets(sss)&&strlen(sss))
        {
            sscanf(sss,"%d%d%d",&a,&b,&c);
            if(c<g[a][b])g[a][b]=g[b][a]=c;
        }
        floyd(n);
        memset(ming,INF,sizeof ming);
        for(i=0;i<f;i++)//更新个居民点据消防站最近距离
        {
            for(j=0;j<ff;j++)
            {
                ming[db[j]]=min(ming[db[j]],g[da[i]][db[j]]);
            }
        }
        int ans=0,ansid=1;
        for(j=0;j<ff;j++)
            ans=max(ans,ming[db[j]]);//原有f座基础上最远距离,若不能有更好情况,答案为1,所以ansid赋初值1
        for(i=0;i<ff;i++)
        {
            int mmin=0;
            for(j=0;j<ff;j++)
                if(i!=j)mmin=max(mmin,min(g[db[i]][db[j]],ming[db[j]]));
            if(mmin<ans)ans=mmin,ansid=db[i];//当ff只有一个,枚举该点时,所有居民点都有一消防站,mmin一定为0,可更新
        }
        printf("%d\n",ansid);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值