标签:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5, M = 1e5; struct Edge { int v, next, idx; Edge(){} Edge(int _v, int _next, int _idx): v(_v), next(_next), idx(_idx){} }e[M]; int dfn[N], deep, head[N], tot; bool iscut[N], isbri[M]; void __init__() { tot = deep = 0; memset(head, -1, sizeof(head)); memset(dfn, 0, sizeof(dfn)); memset(iscut, 0, sizeof(iscut)); memset(isbri, 0, sizeof(isbri)); } void add(int u, int v, int idx) { e[tot] = Edge(v, head[u], idx); head[u] = tot++; } //lowi:i及其子孙通过回边所能走到的最早的祖先的dfn值 int dfs(int u, int fa) { int lowu = dfn[u] = ++deep;//打上时间戳,并初始化low值 int son = 0;//儿子数为0 for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if(!dfn[v]) {//下一个点指向儿子 son++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv >= dfn[u]) iscut[u] = 1;//没有回边,是关节点 if(lowv > dfn[u]) isbri[e[i].idx] = true; } else if(dfn[v] < dfn[u] && v != fa)//指向爷爷,发现回边 lowu = min(lowu, dfn[v]);//利用回边来更新low值 } if(fa == -1 && son == 1) iscut[u] = 0;//仅仅有1个儿子的根结点不是割顶 return lowu; } int main() { __init__(); return 0; }
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/4197164.html