【NOIP模拟赛181007】捉迷藏

题目描述

Anna正在和一群朋友在玩捉迷藏游戏。这种游戏由若干人一起玩,其中一个人为“鬼”,其他人藏在N个房间,由鬼来找这些人。Anna想计算出N(2 <= N <= 20,000)个房间(编号为1……N)中她应该藏哪一间?

Anna知道“鬼”会从房间1开始找。所有房间被M条双向路连接M (1<= M <= 50,000),这种双向路以(A_i,B_i)表示,其中1<=A_i<=N;1<=B_i<=N; A_i!=B_i。通过这些双向路,任意两个房间之间都可以到达。   

Anna觉得离房间1最远的那个房间最安全(相邻两个房间之间的距离为1),请你帮Anna编写一个程序找出她应该躲在哪个房间。

输入

第一行为N和M;第2行至第M+1行,分别包含一条路(A_i,B_i)。

输出

仅有一行,包含三个整数I、J、K,分别表示Anna应该躲的房间号(如果有多解,输出编号最小的)、房间1到Anna躲的房间的距离、Anna可以躲的房间数目。

样例输入

6 7
3 6
4 3
3 2
1 3
1 2
2 4
5 2

样例输出

4 2 3

提示

房间4,5,6 均离起点的距离为2,我们选择4号房间。

代码

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=(j);i<=(k);++i)
#define per(i,j,k) for(register int i=(j);i>=(k);--i)
using namespace std;
template<class T> inline void read(T &x)
{
    x=0;
    register char c=getchar();
    register bool f=0;
    while(!isdigit(c))f^=c=='-',c=getchar();
    while(isdigit(c))x=x*10+c-'0',c=getchar();
    if(f)x=-x;
}
const int N=50001;
int n,m,s=1,u[N],v[N],dis[N],tmp;
int ans1,ans2,ans3;
int main()
{
    read(n),read(m);
    rep(i,1,m)
        read(u[i]),read(v[i]);
    memset(dis,0x7f,sizeof(dis));
    dis[s]=0;
    rep(j,1,n-1)
    {
        tmp=1;
        rep(i,1,m)
        {
            if(dis[v[i]]>dis[u[i]]+1) dis[v[i]]=dis[u[i]]+1,tmp=0;
            if(dis[u[i]]>dis[v[i]]+1) dis[u[i]]=dis[v[i]]+1,tmp=0;  
        }
        if(tmp==1)
            break;
    }
    rep(i,1,n)
        if(dis[i]>ans2) ans2=dis[i],ans1=i,ans3=1;
        else if(dis[i]==ans2) ans3++;
    printf("%d %d %d\n",ans1,ans2,ans3);
    return 0;
}
posted @ 2020-05-02 10:11  牛大了的牛大  阅读(404)  评论(0编辑  收藏  举报