其他分享
首页 > 其他分享> > 基环树求环基本思路

基环树求环基本思路

作者:互联网

什么是基环树?

n条边,n个点,连在一起,就变成了基环树

基环树如何求环?

有人用拓扑排序,但是如果不苛求时间复杂度,可以直接利用栈的思想和dfs进行找环

步骤?

第一步:寻找(任意)一个点进行一次dfs(1,0)

第二步:将所有dfs到的点,存入到栈中

第三步:直到发现连接的点已经访问过了,这时候就相当于找到了一个环

由于dfs的特性,这个时候你只是一直访问了一个路径,一直出栈,相当于就是在你dfs的路径上跳出刚才刚刚找到的点

一直出栈到你发现已经访问过的点

第四步:标记

第五步:对于每一个在环上的点,进行dfs(不在环上,且未dfs过的点)

这个时候dep数组就可以直接输出了

CF131D Subway

 

 1 #include <cstdio>
 2 
 3 const int MAXN=(int)1e4+5;
 4 int ver[MAXN<<1],next[MAXN<<1],head[MAXN],tot;
 5 
 6 void add(int u,int v){
 7     ver[++tot]=v,next[tot]=head[u],head[u]=tot;
 8 }
 9 
10 int sta[MAXN],top,cir[MAXN];
11 bool vis[MAXN],flag;
12 
13 void getcir(int x,int fa){
14     if(flag) return;
15     sta[++top]=x,vis[x]=true;
16     for(int i=head[x];i;i=next[i]){
17         int y=ver[i];
18         if(y==fa) continue;
19         if(vis[y])
20         {
21             cir[y]=true;
22             while(sta[top]!=y){
23                 cir[sta[top--]]=true;
24             }
25             flag=true;
26             return;
27         }
28         getcir(y,x);
29         top--,vis[y]=false;
30     }
31 }
32 
33 int dep[MAXN];
34 void getdep(int x){
35     for(int i=head[x];i;i=next[i]){
36         int y=ver[i];
37         if(dep[y] || cir[y]) continue;
38         dep[y]=dep[x]+1;
39         getdep(y);
40     }
41 }
42 
43 int main(){
44     int n,u,v;
45     scanf("%d",&n);
46     for(int i=1;i<=n;i++)
47     {
48         scanf("%d%d",&u,&v);
49         add(u,v),add(v,u);
50     }
51     getcir(1,0);
52     for(int i=1;i<=n;i++)
53     {
54         if(cir[i]!=false) dep[i]=0,getdep(i);
55     }
56     for(int i=1;i<=n;i++) printf("%d ",dep[i]);
57 }

 

标签:出栈,环上,int,dfs,基环树求,基环树,MAXN,基本思路
来源: https://www.cnblogs.com/rign/p/10803426.html