tarjan算法求联通块中求割点和割边

来源:互联网 发布:人工智能和物联网区别 编辑:程序博客网 时间:2024/06/04 08:41

来自hiho的第五十二周,参考链接:http://hihocoder.com/contest/hiho52/problem/1


//tarjan中可见dfs_pos,low数组不需要初始化//如果有多个联通分块,那么就要枚举每个未访问过的点进行tarjan,进行tarjan前先将fa[i] = -1//这里的se为set,存放割点;edge为vector<pair<int,int> >,存放割边void tarjan(int u){int num_son = 0;//以当前点为树根的子树的个数vis[u] = 1;dfs_pos[u] = low[u] = ++jishu;//dfs_pos为dfs序,low[u]是dfs序最小的祖先(没有则为自己)for(int i = head[u];~i;i = e[i].nex){int v = e[i].v;if(!vis[v]){num_son++;fa[v] = u;//fa是父亲tarjan(v);low[u] = min(low[u],low[v]);//递归求dfs序最小的的祖先if(fa[u] == -1 && num_son > 1)//若当前节点没有父亲且有两个或两个以上子树,则这个点必为割点se.insert(u);if(fa[u] != -1 && low[v] >= dfs_pos[u])//若当前点存在父亲,且他的儿子中没有回边连到u或者u的祖先中,此点为割点se.insert(u);if(low[v] > dfs_pos[u])//他的儿子没有回边连到u的祖先中edge.push_back(pii(min(u,v),max(u,v)));}else if(v != fa[u])//如果拜访到已经被访问的点low[u] = min(low[u],low[v]);}}


0 0
原创粉丝点击