现在的位置: 首页 > 综合 > 正文

bzoj3402 [Usaco2009 Open]Hide and Seek 捉迷藏

2018年01月13日 ⁄ 综合 ⁄ 共 1342字 ⁄ 字号 评论关闭

Description

    贝茜在和约翰玩一个“捉迷藏”的游戏.
    她正要找出所有适合她躲藏的安全牛棚.一共有N(2≤N≤20000)个牛棚,被编为1到N号.她知道约翰(捉牛者)从牛棚1出发.所有的牛棚由M(1≤M≤50000)条双向路连接,每条双向路连接两个不同的牛棚.所有的牛棚都是相通的.贝茜认为同牛棚1距离最远的的牛棚是安全的.两个牛棚间的距离是指,从一个牛棚到另一个牛棚最少需要通过的道路数量.请帮贝茜找出所有的安全牛棚.

Input

    第1行输入两个整数N和M,之后M行每行输入两个整数,表示一条路的两个端点.
   

Output

 仅一行,输出三个整数.第1个表示安全牛棚(如果有多个,输出编号最小的);第2个表示牛棚1和安全牛棚的距离;第3个表示有多少个安全的牛棚.

Sample Input

6 7

3 6

4 3

3 2

1 3

1 2

2 4

5 2

Sample Output

4 2 3

跑一遍spfa,然后倒着搜更新那三个数就行了

#include<cstdio>
#include<cstring>
struct edge{
	int to,next,v;
}e[200001];
int head[50001];
int dis[50001];
int q[500001];
bool mrk[50001];
int n,m,cnt,t,w=1,mx=0,rep,num;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void ins(int u,int v,int w)
{
	e[++cnt].v=w;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
inline void insert(int u,int v,int w)
{
	ins(u,v,w);
	ins(v,u,w);
}
inline void spfa()
{
	memset(dis,127/3,sizeof(dis));
	q[1]=1;dis[1]=0;mrk[1]=1;
	while (t<w)
	{
		int now=q[++t];
		for (int i=head[now];i;i=e[i].next)
		  if (dis[e[i].to]>dis[now]+e[i].v)
		  {
		  	dis[e[i].to]=dis[now]+e[i].v;
		  	if (!mrk[e[i].to])
		  	{
		  		q[++w]=e[i].to;
		  		mrk[e[i].to]=1;
		  	}
		  }
		mrk[now]=0;
	}
}
int main()
{
	n=read();
	m=read();
	for (int i=1;i<=m;i++)
	  {
	  	int x=read(),y=read();
	  	insert(x,y,1);
	  }
	spfa();
	for (int i=n;i>=2;i--)
	{
		if (dis[i]>mx)
		{
			mx=dis[i];
			num=i;
			rep=1;
		}else
		if (dis[i]==mx)
		{
			num=i;
			rep++;
		}
	}
	printf("%d %d %d\n",num,mx,rep);
	return 0;
}

抱歉!评论已关闭.