ZOJ:2913 Bus Pass

典型的BFS。

基本思路:从每条线路上的每个地区z出发进行BFS遍历;对每个地区j,如果地区j是最终求得的中心地区,则要保证从它出发能到达每条路上每个地区z,并且选择的星形阈值要尽可能的小,因此统计每个地区z到地区j最短距离中的最大值,这个最大值记录在数组元素step[j]中;最后求得的最小的星形阈值就是每个地区j的step[j]的最小值,中心地区就是取得最小值的地区j。

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define MAXN 10000
#define INF 1000000
using namespace std;
int step[MAXN+5];
int ans[MAXN+5];
int area[10005][12];
bool used[MAXN+5];
bool vis[MAXN+5];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(area,-1,sizeof(area));
        int nz,nr;
        scanf("%d%d",&nz,&nr);
        for(int i=0; i<nz; ++i)
        {
            int _id;
            scanf("%d",&_id);
            scanf("%d",&area[_id][0]);
            for(int j=1; j<=area[_id][0]; ++j)
                scanf("%d",&area[_id][j]);
        }
        memset(ans,0x80,sizeof(ans));
        memset(used,0,sizeof(used));
        for(int i=0; i<nr; ++i)
        {
            int n;
            scanf("%d",&n);
            for(int ii=0; ii<n; ++ii)
            {
                int tmp;
                scanf("%d",&tmp);
                if(used[tmp]) continue;
                else used[tmp]=true;
                queue<int> q;
                memset(step,0,sizeof(step));
                memset(vis,0,sizeof(vis));
                q.push(tmp);
                vis[tmp]=true;
                while(!q.empty())
                {
                    int t=q.front();
                    q.pop();
                    for(int j=1; j<=area[t][0]; ++j)
                        if(!vis[area[t][j]])
                        {
                            step[area[t][j]]=step[t]+1;
                            vis[area[t][j]]=true;
                            q.push(area[t][j]);
                        }
                }
                for(int j=1; j<=MAXN; ++j)
                    if(area[j][0]!=-1)
                        ans[j]=max(ans[j],step[j]);
            }
        }
        int res=INF,pos;
        for(int i=1; i<=MAXN; ++i)
            if(area[i][0]!=-1)
            {
                if(ans[i]<res)
                {
                    res=ans[i];
                    pos=i;
                }
            }
        printf("%d %d\n",res+1,pos);
    }
    return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值