tarjan算法
zhouyiran_2011 · · 算法·理论
补档 tarjan
tarjan求强连通分量代码
void tarjan(int u)
{
dfn[u]=low[u]=++cnt;
vis[u]=1;
st.push(u);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if (!dfn[v])
{
tarjan(v);
low[u]=min(low[u], low[v]);
}
else if(vis[v])
low[u]=min(low[u], dfn[v]);
}
if(dfn[u]==low[u])
{
tot++;
int v;
do
{
v=st.top();
st.pop();
col[v]=tot;
vis[v]=0;
}while(v!=u);
}
}
缩点代码
void Tarjan(int x)
{
dfn[x]=low[x]=++id;
s.push(x);
vis[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(!dfn[v])
{
Tarjan(v);
low[x]=min(low[v],low[x]);
}
else if(vis[v])
{
low[x]=min(low[x],dfn[v]);
}
}
if(dfn[x]==low[x])
{
++tot;
while(s.top()!=x)
{
int temp=s.top();
s.pop();
is[temp]=tot;
vis[temp]=0;
}
int temp=s.top();
s.pop();
is[temp]=tot;
vis[temp]=0;
}
}
求割点
void tarjan(int u)
{
int son=0;
dfn[u]=low[u]=++idx;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u], low[v]);
if(low[v]>=dfn[u])
{
son++;
if(u!=root||son>1)
{
cut[u]=1;
}
}
}
else
low[u]=min(low[u], dfn[v]);
}
}
求割边
void tarjan(int u,int edg)
{
dfn[u]=low[u]=++idx;
for(int i=head[u];i;i=edge[i].next)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v, i);
low[u]=min(low[u], low[v]);
if(dfn[u]<low[v])
{
bri[edge[i].id]=1;
cnt++;
}
}
else if(i!=(edg^1))
{
low[u]=min(low[u],dfn[v]);
}
}
}