求连通分量个数+判定二分图

今天做了一个错误的决定,学习新的知识,明天把生成树的东西总结一下
//
深度优先遍历框架 vector<int> G[maxn]; int vis[maxn]; void dfs(int u) { vis[u]=1; PREVISIT(u);//访问节点u之前的操作 for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!vis[v]) dfs(v); } POSITIVE(u);//访问u之后的操作 } //计算出每个节点所属的连通分量 void find_cc() { curent_cc=0; memset(vis,0;sizeof(vis)); for(int i=0;i<n;i++) if(!vis[i]) { curent_cc++; dfs(i); } } //判定u所在的连通分量是否为二分图 //二分图的特点,每一条边连接的两个点属于不同的集合,所以我们可以用黑白二色来代表 //两个不同的集合,所以沿着一个节点搜索它的相邻节点,相邻节点没有被访问,则染成它的相反色 //如果碰到了一个相邻节点已经被访问过,且其着的颜色相同的,则证明不是二分图, int color[maxn]; bool f(int u) { for(int i=0;i<G[u].size();i++) //遍历i节点的所有子节点 { v=G[u][i]; if(color[v]==color[u]) return false;//如果遇到相同颜色,则不是二分图,返回假 if(!color[v]) { color[v]=3-color[u];//未被访问,染成相反颜色 if(!f(v))//如果从子节点v向下搜索,遇到了两个相邻节点染同一色,则返回假 return false; } } return true; }

猜你喜欢

转载自www.cnblogs.com/rainyskywx/p/10004481.html