tarjan强连通分量求割点

来源:互联网 发布:外汇投资收益率知乎 编辑:程序博客网 时间:2024/06/14 01:42

上一篇文章http://blog.csdn.net/myhyh/article/details/72803454
接着上一篇文章说,如果对于一个点i,从i出发到点j的dfs如果没能转回比i出现的更早出现的点,那么点j和j后面的点其实是一个转不出去的整块
那么从图中删除点i的话,j所属的那块就会从图中独立出去,这时i就是所谓的割点。
而上一篇文章中求出的low[j]正好就是点j能转回的最早点的时间,如果low[j]>=dfn[i],i就是割点
上篇写的是邻接矩阵的,这篇就写邻接表的

#include <iostream>#include <string.h>#include <vector>using namespace std;vector<vector<int>> graph;int vis[11000];int dfn[11000];int stk[11000];int low[11000];int counts[11000];      //counts[i]=删除点i增加的块的数量int stktop=0;int ind=1;int n;void init(){    graph.resize(11000);    graph.clear();    memset(vis,0,sizeof(vis));    memset(dfn,0,sizeof(dfn));    memset(stk,0,sizeof(stk));    memset(low,0,sizeof(low));    memset(counts,0,sizeof(counts));}void tarjan(int pos){    dfn[pos]=low[pos]=ind++;    stk[stktop++]=pos;    vis[pos]=1;    for(int i=0;i<graph[pos].size();i++)    {        if(!dfn[graph[pos][i]])        {            tarjan(graph[pos][i]);            if(low[graph[pos][i]]>=dfn[pos])                counts[pos]++;            low[pos]=low[graph[pos][i]]<low[pos]?low[graph[pos][i]]:low[pos];        }        else if (vis[graph[pos][i]])        {            low[pos]=dfn[graph[pos][i]]<low[pos]?dfn[graph[pos][i]]:low[pos];        }    }    if(counts[pos]>maxcount)        maxcount=counts[pos];}