【模板】——tarjan (附:缩点)
tarjan算法的模板
void tarjan(int u)
{
dfn[u]=low[u]=++js;//dfn即时间戳,js即计数,low[u]即与u点形成强联通的第一个点
st[++top]=u;
for(int i=head[u];i;i=mapp[i].next;)
{
int v=mapp[i].value;
if(!dfn[v])//未染色的点(白点)
{
tarjan(v);
low[u]=min(low[v],low[u]);
}
else if(!lt[u])//已入栈,但未出栈的点(灰点)
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])//记录各个强联通的编号
{
lt[u]=++lts;//lt[u]即u点属于的强联通的编号;lts即联通数(强联通的编号)
while(st[top]!=u)
lt[st[top--]]=lts;
lts--;
}
}
附:缩点(该段代码直接插入到主函数调用tarjan算法之后即可)
for(int i=1;i<=n;i++)//缩点并执行操作
for(int j=head[i];j;j=mapp[j].next)
{
int v=mapp[j].value;
/*
if(lt[i]!=lt[v])//记录缩完点后每一个点的入读和初度
{
out[lt[i]]++;
in[lt[v]]++;
}
*/
/*
add(lt[u],lt[v]);//重新建一个图(有向无环)
*/
}