【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; }