CSU 1526: Beam me out!

题意:第一问:从1出发,是不是会走进一个点,然后再也到不了n。

        第二问:是不是存在一个环,从1出发可以走到。

对于第一问,我们可以先缩点,然后看看是不是只有一个点,出度为0,还有注意这个点包含n

对于第二问,如果访问的点数sum等于缩点以后的点数,那么就是没有环了。

这里需要注意的是,特判自环......wa成狗

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#define LL long long
#define maxn 50010
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;

int pre[maxn],low[maxn],dfs_time,n,cnt;
int scc[maxn] ;
bool vi[maxn],flag,hehe;
stack<int>s;
vector<int>qe[maxn] ;
void dfs( int u )
{
    pre[u] = low[u] = ++dfs_time ;
    int i , v ;
    s.push(u) ;
    vi[u] = 1 ;
    if(u==n) flag=true;
    for( i = 0 ; i < qe[u].size() ; i++ )
    {
        v = qe[u][i] ;
        if(v==u)hehe=true;
        if(!pre[v]){
            dfs(v) ;
             low[u] = min(low[u],low[v]) ;
        }
        if( vi[v] && pre[v] < low[u])
            low[u] = pre[v] ;
    }
    if(pre[u] == low[u])
    {
        cnt++ ;
        while(1)
        {
            v = s.top() ; s.pop() ;
            vi[v] = 0 ;
            scc[v]=cnt;
            if(v==u) break ;
        }
    }
    return ;
}
void solve(int n)
{
    memset(pre,0,sizeof(pre)) ;
    memset(vi,0,sizeof(vi)) ;
    while(!s.empty())s.pop();
    dfs_time=cnt=0;
    flag=false;
    dfs(1) ;
    memset(vi,0,sizeof(vi)) ;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<qe[i].size();j++)
        {
            int v=qe[i][j] ;
            if(scc[v]!=scc[i])
            {
                vi[scc[i]]=1;
            }
        }
    }
    int cnt1=0;
    for(int i=1;i<=cnt;i++)if(!vi[i])
        cnt1++ ;
    if(cnt1==1&&flag)printf("PARDON ");
    else printf("PRISON ");
    cnt1=0;
    for(int i=1;i<=n;i++)if(pre[i])
    {
        cnt1++ ;
    }
    if(cnt1==cnt&&!hehe)puts("LIMITED");
    else puts("UNLIMITED");
}
int main()
{
    int sz,i,j,k;
    int t,ans,m ;
     while(scanf("%d",&n)!=EOF){
        hehe=false;
        for(i=1;i<=n;i++)qe[i].clear();
        for(i=1;i<n;i++)
        {
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d",&k) ;
                qe[i].push_back(k) ;
            }
        }
        solve(n) ;
     }
    return 0;
}
View Code

 

posted @ 2015-05-07 22:33  _log__  阅读(186)  评论(0编辑  收藏  举报