详细讲解 :http://www.byvoid.com/blog/biconnect/
求割边模版
//hint:所给图必须为连通图 const int N=100100; struct cutting_edge{ int cnt,scnt; int dfn[N],low[N],vis[N]; vector< pair<int,int> > G[N]; void init(int n){ for(int i=0;i<=n;i++){ G[i].clear(); vis[i]=0; } } void add(int u,int v,int id){ G[u].push_back(make_pair(v,id)); G[v].push_back(make_pair(u,id)); } void dfs(int u,int father){ dfn[u]=low[u]=++cnt; vis[u]=1; for(int i=0;i<G[u].size();i++){ int v=G[u][i].first; int id=G[u][i].second; if(vis[v]&&id!=father) low[u]=min(dfn[v],low[u]); else if(!vis[v]) { dfs(v,id); low[u]=min(low[u],low[v]); if(dfn[u]<low[v]) { //此时u->v 为割边 scnt++; } } } } int tarjan(int n){ cnt=0; scnt=0; dfs( 0,-1 ); return scnt; } }ce;
求割点模版
//hint:所个图必须为连通图; //无向图求割点; //读入n(顶点个数,范围1 -- n); //返回 isgd[], 当isgd[i]=true,i为割点;割点个数scnt; const int N=100005; struct cutting_point{ vector< pair<int,int> > G[N]; int cnt,scnt; int dfn[N],low[N],f[N],vis[N]; bool isgd[N]; void init(int n){ for(int i=0;i<=n;i++) { vis[i]=0; isgd[i]=0; G[i].clear(); } } void add(int u,int v,int id){ G[u].push_back(make_pair(v,id)); G[v].push_back(make_pair(u,id)); } void dfs(int u,int p){ dfn[u]=low[u]=++cnt; f[u]=p; vis[u]=1; for(int i=0;i<G[u].size();i++){ int v=G[u][i].first; int id=G[u][i].second; if(vis[v]&&id!=p) low[u]=min(dfn[v],low[u]); else if(!vis[v]) { dfs(v,u); low[u]=min(low[u],low[v]); } } } int tarjan(int n){ int rc=0; cnt=0; scnt=0; dfs(1,-1); for(int i=2;i<=n;i++){ //判断割点 int u=f[i]; if(u==1) rc++; else if(dfn[u]<=low[i]) isgd[u]=true; } if(rc>=2) isgd[1]=true; for(int i=1;i<=n;i++){ //求割点总数 if(isgd[i]==true) scnt++; } return scnt; } }cp;