【模板】——tarjan (附:縮點)
阿新 • • 發佈:2022-05-07
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]);//重新建一個圖(有向無環) */ }