大学的时光是值得怀念的,有多少事情珍藏在我们的记忆里,又有多少人我们一辈子都忘不掉。 123abc是一个不起眼的小男孩,他曾经在很多方面努力过,也经历了很多失败,在这些努力和失败中,他收获了自己的人生。 whx是123abc认识的一个女生,123abc很喜欢她,总是用各种方法想见到她,可是whx生气了, 她不想见到123abc,这令123abc很伤心。 whx明天就要离开吉林大学了,123abc想看她最后一眼,虽然whx不想看到不起眼的123abc,但是123abc只想看她最后一眼,内心默默祝福她。根据可靠线报,whx将从地点1出发,最后到达地点n (2<=n<=10000),然后离开长春,这是最后一次机会,123abc不想错过这次机会,于是他也得到了长春市的所有地形。每个地点被标号为1—n,其中1表示吉林大学,n表示火车站,其他表示长春市的其他地点,若两个地点有公交车或者轻轨直达,则之间有一条路(这是一个无向图,注意啊)。边数为m(0<=m<=400000). 123abc现在想知道,除了吉林大学和火车站,还有多少地方一定可以等到whx(因为地点1和n太明显了,whx会更生气的,还是邂逅比较好)。
Input
每组测试数据第一行n和m,接下来的m行每行两个数x,y(1<=x<=n,1<=y<=n),表示地点x和地点y是可以相互到达的。每组测试数据以空行结束。
Output
分为三种情况; 1.从1到n没有路,则输出Information Error! 2.从1到n的路都经过的点数(除了1和n)为0,输出Poor 123abc! 3.否则输出这样地点的个数
Sample Input
2 1 1 2 3 0 8 6 1 2 1 3 2 3 3 8 8 5 8 6
Sample Output
Poor 123abc! Information Error! 1
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=820000;
//找1->n路上的必经之地(点) 不包括1和n
struct edge
{
int t,w;
int next;
};
int V,E;
int p[maxn];
edge G[maxn];
int l;
void init()
{
memset(p,-1,sizeof(p));
l=0;
}
void addedge(int u,int t,int w,int l)
{
G[l].t=t;
G[l].w=w;
G[l].next=p[u];
p[u]=l;
}
//tarjan
int cut[maxn];//cut[i]非0表示i是割点
int color[maxn];//颜色:0表示没有访问,1表示正在访问,2表示访问结束
int lowc[maxn];//表示i及i的子孙相连的辈分最高的祖先节点所在的深度
int d[maxn];//表示i节点在树中的深度
int root;//根节点
int pcnt;
int cnt;//1->n路上的必经之地(点)个数 不包括1和n
void dfs(int u,int fath,int deep)
{
color[u]=1;
lowc[u]=d[u]=deep;
int tot=0;//子树个数
for(int i=p[u];i!=-1;i=G[i].next)
{
int t=G[i].t;
if(t!=fath&&color[t]==1)
{
lowc[u]=min(lowc[u],d[t]);
}
int tag=color[V];
if(color[t]==0)
{
dfs(t,u,deep+1);
tot++;
lowc[u]=min(lowc[u],lowc[t]);
//求割点
if((u==root&&tot>1)||(u!=root&&lowc[t]>=d[u])) //cut[u]=1;
{
//不能包含1和n,root=1; 所以可以cnt++
if(u!=1&&u!=V&&tag==0&&color[V]!=0) cnt++;
}
//求割边
//if(lowc[t]>d[u]) edge[u][t]=true; u->t是割边
}
}
color[u]=2;
}
void calc()
{
pcnt=0;
memset(cut,0,sizeof(cut));
memset(color,0,sizeof(color));
memset(lowc,0,sizeof(lowc));
memset(d,0,sizeof(d));
root=1;
dfs(root,-1,1);
//for(int i=1;i<=V;i++) if(cut[i]) pcnt++;
}
int main()
{
while(scanf("%d%d",&V,&E)==2)
{
init();
for(int i=0;i<E;i++)
{
int u,v;scanf("%d%d",&u,&v);
addedge(u,v,1,l++);
addedge(v,u,1,l++);
}
cnt=0;
calc();
if(color[V]==0)//1和n不联通
{
printf("Information Error!\n");
continue;
}
if(cnt) printf("%d\n",cnt);
else printf("Poor 123abc!\n");
}
return 0;
}
/*
8 6
1 2
2 8
1 4
4 8
4 5
4 6
*/