• 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
  • 相关阅读:
    HDU 1394 Minimum Inversion Number
    HDU 4931 Happy Three Friends
    BZOJ 1089 严格n元树 (递推+高精度)
    BZOJ 1088 扫雷Mine (递推)
    BZOJ 3038 上帝造题的七分钟2 (并查集+树状数组)
    BZOJ 3211 花神游历各国 (树状数组+并查集)
    BZOJ 1087 互不侵犯King (位运算)
    BZOJ 1002 轮状病毒 (基尔霍夫矩阵)
    BZOJ 1005 明明的烦恼 (组合数学)
    BZOJ 1058 报表统计 (STL)
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/4486340.html
Copyright © 2020-2023  润新知