无向图找环
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无向图找环相关的知识,希望对你有一定的参考价值。
无向图找环
1.用记录深度的方法
void dfs(int u,int s){
d[u]=s;
for(int i=h[u];i;i=e[i].nt){
int v=e[i].to;
if(d[v]){ //如果有深度说明之前访问过,可能存在环.
ans=max(ans,d[v]-d[u]+1);
}
else dfs(v,s+1);
}
}
如果 v v v是 u u u的前驱结点的话不受影响,因为 d [ v ] + 1 = d [ u ] d[v]+1=d[u] d[v]+1=d[u]
所以 d [ v ] − d [ u ] + 1 = − 1 + 1 = 0 d[v]-d[u]+1=-1+1=0 d[v]−d[u]+1=−1+1=0,对 a n s ans ans无影响。
该方法只能记录简单环的最大长度。
例题是 P O J 3985 POJ3985 POJ3985
对于下面这种图
该方法得到的 a n s = 6 ans=6 ans=6,也就是 1 − 4 − 3 − 5 − 2 − 6 1-4-3-5-2-6 1−4−3−5−2−6 这个环。
如果尝试用这种方法记录环的个数的话,可能会出现问题。
void dfs(int u,int s){
d[u]=s;
for(int i=h[u];i;i=e[i].nt){
int v=e[i].to;
if(d[v]){
int len=d[v]-d[u]+1;
//printf("(%d,%d) %d\\n",u,v,len);
if(len>2) num++;
ans=max(ans,len);
}
else dfs(v,s+1);
}
}
还是上图, n u m = 2 num=2 num=2。
因为此时 d f s dfs dfs的顺序是: 1 − 4 − 3 − 5 − 2 − 6 1-4-3-5-2-6 1−4−3−5−2−6
只会在访问 e d g e ( 1 , 5 ) , e d g e ( 1 , 6 ) edge(1,5),edge(1,6) edge(1,5),edge(1,6) 时产生贡献。
因此会漏掉 1 − 5 − 2 − 6 1-5-2-6 1−5−2−6 这个环。
2.记录深度+标记的方法。
void dfs(int u,int s){
d[u]=s,vis[u]=1;
for(int i=h[u];i;i=e[i].nt){
int v=e[i].to;
if(!vis[v]) dfs(v,s+1);
else if(vis[v]==1){
int len=d[u]-d[v]+1;
if(len>2) num++;
ans=max(ans,d[u]-d[v]+1);
}
}vis[u]=2;
}
与方法一实质一样,都只能统计简单环。唯一区别是它会把先搜索完的结点标记为2不可再搜。
以上是关于无向图找环的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 6370 Werewolf 2018 Multi-University Training Contest 6 (DFS找环)