Tarjan算法总结
Posted lslzf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tarjan算法总结相关的知识,希望对你有一定的参考价值。
边双联通分量
inline void Tarjan(int x,int inedge)
{
dfn[x]=low[x]=++cnt;
for(int i=Last[x];i;i=e[i].next)
{
int y=e[i].ver;
if(!dfn[y])
{
Tarjan(y,i);
low[x]=min(low[x],low[y]);
if(low[y]>dfn[x])e[i].flag=e[i^1].flag=true;
}
else if(i!=(inedge^1))low[x]=min(low[x],dfn[y]);
}
}
inline void dfs(int x)
{
con[x]=tot;
for(int i=Last[x];i;i=e[i].next)
{
if(e[i].flag)continue;
int y=e[i].ver;
if(!con[y])dfs(y);
}
}
inline void colored(void)
{
for(int i=1;i<=n;i++)
if(!con[i])++tot,dfs(i);
}
点双连通分量
inline void Tarjan(int x,int root)
{
dfn[x]=low[x]=++cnt;
Stack.push(x);
int flag=0;
if(x==root&&!Last[x])
{
Stack.pop();T++;
cut[x]=true;
con[T].push_back(x);
return;
}
for(int i=Last[x];i;i=e[i].next)
{
int y=e[i].ver;
if(!dfn[y])
{
Tarjan(y,root);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
int top=0;T++;
while(top!=y)
{
top=Stack.top();
Stack.pop();
con[T].push_back(top);
}
con[T].push_back(x);
flag++;
if(x!=root||flag>1)cut[x]=true;
}
}
else low[x]=min(low[x],dfn[y]);
}
}
强连通分量
void Tarjan(int x)
{
dfn[x]=low[x]=++tim;
s[++top]=x;
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(!dfn[y]){
Tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(!sccno[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
cnt++;
while(1){
int y=s[top--];
sccno[y]=cnt;
num[cnt]++;
if(y==x) break;
}
}
}
以上是关于Tarjan算法总结的主要内容,如果未能解决你的问题,请参考以下文章