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; }