首页 > 代码库 > HDU 3594 Cactus(仙人掌问题)
HDU 3594 Cactus(仙人掌问题)
http://acm.hdu.edu.cn/showproblem.php?pid=3594
题意:
一个有向图,判断是否强连通和每条边只在一个环中。
思路:
仙人掌问题。
用Tarjan算法判断强连通分量的时候,记录每节结点的父节点。当找到一个环后,回溯将该环上的所有结点+1,如果有结点出现2次了,则说明不是仙人掌了。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<queue> 7 #include<cmath> 8 #include<map> 9 #include<stack>10 using namespace std;11 12 const int maxn=20000+5;13 14 int n,m;15 16 vector<int> G[maxn];17 int in[maxn];18 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;19 int fa[maxn];20 21 22 int find(int u,int v)23 {24 while(fa[u]!=v)25 {26 in[u]++;27 if(in[u]>1) return 0;28 u=fa[u];29 }30 return 1;31 }32 33 int dfs(int u)34 {35 pre[u]=lowlink[u]=++dfs_clock;36 for(int i=0;i<G[u].size();i++)37 {38 int v=G[u][i];39 if(!pre[v])40 {41 fa[v]=u;42 if(!dfs(v)) return 0;43 lowlink[u]=min(lowlink[u],lowlink[v]);44 }45 else if(!sccno[v])46 {47 lowlink[u]=min(lowlink[u],pre[v]);48 if(!find(u,v)) return 0;49 }50 }51 if(lowlink[u]==pre[u])52 {53 scc_cnt++;54 if(scc_cnt>1) return 0;55 }56 return 1;57 }58 59 int find_scc()60 {61 dfs_clock=scc_cnt=0;62 memset(sccno,0,sizeof(sccno));63 memset(pre,0,sizeof(pre));64 memset(in,0,sizeof(in));65 memset(fa,0,sizeof(fa));66 for(int i=0;i<n;i++)67 if(!pre[i]) if(!dfs(i)) return 0;68 return 1;69 }70 71 int main()72 {73 //freopen("D:\\input.txt","r",stdin);74 int T;75 scanf("%d",&T);76 while(T--)77 {78 scanf("%d",&n);79 for(int i=0;i<n;i++) G[i].clear();80 while(true)81 {82 int u,v;83 scanf("%d%d",&u,&v);84 if(u==0 && v==0) break;85 G[u].push_back(v);86 }87 if(find_scc() && scc_cnt==1) cout<<"YES"<<endl;88 else cout<<"NO"<<endl;89 }90 return 0;91 }
HDU 3594 Cactus(仙人掌问题)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。