[[TOC]]
找环
基环树上找环
原理
基环树: 只有一个环的无向图.
问: 如何找到基环树上的所有环上的点,和环上的边.

代码
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 1e6+5;
const int maxe = 1e6+5;
int n,m;
struct linkList {
typedef struct {int u,v,w,next;} edge;
edge e[maxe];
int h[maxn],edge_cnt=0;
linkList(){
edge_cnt=0;
memset(h,-1,sizeof(h));
}
//遍历点u 周围点
template<typename U>
void for_each(int u,U func){
for(int i = h[u] ; i !=-1;i = e[i].next)
func(e[i].u,e[i].v,e[i].w); //u v w
}
void add(int u,int v,int w=0){
e[edge_cnt] = {u,v,w,h[u]};
h[u] = edge_cnt++;
}
void add2(int u,int v,int w=0){
add(u,v,w);
add(v,u,w);
}
//下标访问
edge& operator[](int i){ return e[i]; }
//返回head[u]
int operator()(int u){ return h[u]; }
} e;
//读取数据
void init() {
std::cin >> n >> m;
for(int i=1;i<=m;++i){
int u,v;
std::cin >> u >> v;
e.add2(u,v);
}
}
int dfn[maxn];
bool node_color[maxn]; //标记环上的点
bool edge_color[maxe]; // 标记环上边
//
int fa[maxn]; //每个点的父子边
//找环上的点与边
//u是dfn大的点
void get_cycle(int u,int v,int c) {
edge_color[c] = 1;
node_color[u] = 1;
node_color[v] = 1;
while( u != v) {
u = e[fa[u]].u;
node_color[u] = 1;
}
}
int timestamp; // idx
//dfs 序查找 环上的点与边
void dfs(int u,int father) {
dfn[u] = ++ timestamp;
for(int i = e.h[u]; ~i;i= e[i].next) {
int v = e[i].v;
if( v == father) continue;
if( !dfn[v]) { //没有访问过
fa[v] = i; //记录父子边
dfs(v,u);
}
else if ( dfn[v] < dfn[u])
get_cycle(u, v,i);
}
}
int main(){
init();
dfs(1,0);
//输出环上的点
for(int i=1;i<=n;++i){
cout << " node "<< i <<" in loop : ";
if(node_color[i])
std::cout << "yes\n" ;
else
std::cout << "no\n" ;
}
return 0;
}
普通图上的环
TODO