您的位置:首页 > 其它

tarjan模板(缩点,求有向图强连通分量)

2016-05-04 15:53 316 查看
具体思路见详解网址:https://www.byvoid.com/blog/scc-tarjan

然后整理出了这个tarjan模板,具体数组的功能代码都有注释。

const int N=100010;
struct data
{
int to,next;
} tu[N*2];
int head
;
int ip;
int dfn
, low
;///dfn[]表示深搜的步数,low[u]表示u或u的子树能够追溯到的最早的栈中节点的次序号
int sccno
;///缩点数组,表示某个点对应的缩点值
int step;
int scc_cnt;///强连通分量个数
void init()
{
ip=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
tu[ip].to=v,tu[ip].next=head[u],head[u]=ip++;
}
vector<int> scc
;///得出来的缩点,scc[i]里面存i这个缩点具体缩了哪些点
stack<int> S;
void dfs(int u)
{
dfn[u] = low[u] = ++step;
S.push(u);
for (int i = head[u]; i !=-1; i=tu[i].next)
{
int v = tu[i].to;
if (!dfn[v])
{
dfs(v);
low[u] = min(low[u], low[v]);
}
else if (!sccno[v])
low[u] = min(low[u], dfn[v]);
}
if (low[u] == dfn[u])
{
scc_cnt += 1;
scc[scc_cnt].clear();
while(1)
{
int x = S.top();
S.pop();
if (sccno[x] != scc_cnt) scc[scc_cnt].push_back(x);
sccno[x] = scc_cnt;
if (x == u) break;
}
}
}
void tarjan(int n)
{
memset(sccno, 0, sizeof(sccno));
memset(dfn, 0, sizeof(dfn));
step = scc_cnt = 0;
for (int i = 1; i <=n; i++)
if (!dfn[i]) dfs(i);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: