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

joj 2607: Last time see you again 求1->n路上的必经之地(点)

2013年10月27日 ⁄ 综合 ⁄ 共 2595字 ⁄ 字号 评论关闭
文章目录

 

 

大学的时光是值得怀念的,有多少事情珍藏在我们的记忆里,又有多少人我们一辈子都忘不掉。 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
*/

 

 

抱歉!评论已关闭.