cogs 774. [USACO Open09] 捉迷藏
★☆ 输入文件:hideseek.in
输出文件:hideseek.out
简单对比
时间限制:1 s 内存限制:128 MB
Bessie正在玩捉迷藏游戏。(捉迷藏是这样玩的:在制定了奖罚规则后,玩家分为“捉”和“藏”两种,“藏”者有多个,在他们都藏起来后,由单独的一个“捉”者去找他们,这个游戏玩起来真是其乐无穷!)
Bessie正在盘算她要藏到哪个牛棚里,一共有N(2 <= N <= 20,000)个牛棚,编号为1~N。她知道“捉”者FJ会从1号牛棚开始找。有M(1<= M <= 50,000)条无向通路连接着所有的牛棚,其中通路i的两个端点分别为A_i和B_i(1<= A_i <= N; 1 <= B_i <= N; A_i != B_i),任意两个牛棚之间都可互达。
Bessie觉得藏到跟1号牛棚距离最远的牛棚里会比较安全,(这里两个牛棚之间的距离是指从一个牛棚到另一个牛棚的最短路径),请帮Bessie算一下最佳躲藏位置。
输入格式:
第1行:两个空格隔开的整数N,M;
第2~M+1行:第i+1行有两个整数A_i,B_i,即第i条路的两个端点;
输出格式:
一行,三个空格隔开的整数,分别为:离1号牛棚最远的牛棚编号(如果最远的有多个,输出编号最小的那个);最远的牛棚与1号牛棚的最短路径;拥有此最短路径的牛棚个数。
输入输出样例:
hideseek.in
6 7
3 6
4 3
3 2
1 3
1 2
2 4
5 2
输入样例说明:
输入数据如图所示:
1--2--5
| /|
|/ |
3--4
|
6
hideseek.out
4 2 3
输出样例解释:
4,5,6号牛棚距1号牛棚的最短路径均为2,选4号输出是因为它的编号最小。
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int N=20010; const int M=50010; const int INF=9999999; int head[N],dis[N]; bool vis[N]; int now=1,n,m; struct node{ int u,v,w,nxt; }E[M<<1]; int maxdis,cnt,number; inline int read() { int x=0;char c=getchar(); while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); return x; } inline void add(int u,int v) { E[now].v=v; E[now].w=1; E[now].nxt=head[u]; head[u]=now++; } inline void spfa(int start) { queue<int>Q; for(int i=1;i<=n;i++) dis[i]=INF; dis[start]=0; Q.push(start); while(!Q.empty()) { int topp=Q.front(); Q.pop(); vis[topp]=0; for(int i=head[topp];~i;i=E[i].nxt) if(dis[E[i].v]>dis[topp]+E[i].w) { dis[E[i].v]=dis[topp]+E[i].w; if(!vis[E[i].v]) vis[E[i].v]=1, Q.push(E[i].v); } } } int main() { freopen("hideseek.in","r",stdin); freopen("hideseek.out","w",stdout); n=read(),m=read(); for(int i=1;i<=n;i++) head[i]=-1; for(int i=1;i<=m;i++) { int u=read(),v=read(); add(u,v); add(v,u); } spfa(1); for(int i=1;i<=n;i++) if(dis[i]>maxdis) maxdis=dis[i], number=i, cnt=1; else if(dis[i]==maxdis) cnt++; printf("%d %d %d",number,maxdis,cnt); return 0; } /* 6 7 3 6 4 3 3 2 1 3 1 2 2 4 5 2 */