1)有向圖中,該圖中的任意兩點之間可互達。
2)乙個乙個點也是強連通分量
1)時間戳 dfn[ x ]
時間戳是用來標記圖中每個節點在進行深度優先搜尋時被訪問的時間順序,當然,你可以理解成乙個序號(這個序號由小到 大),用 dfn[x] 來表示(搜到該點的最早時間)
2)low陣列
2)low陣列 : low[x] 表示 x是從哪個點(這個環中最早遍歷到的那個點的 low 值 ) 組成的環,如果這幾個點組成乙個環,則這幾個點 low值 都是相同,因為他們從某個點開始遍歷,最終還能回到這個點。
每次搜乙個結點 初始化 dfn [x] = low [x] = ++tot 如果該節點沒有被訪問過就dfs訪問他的出邊,然後併入棧,在回溯的過程中更新該點的low[x]值 low[x] = min(low[x], low[y] ),看x 和 y 都是以哪個點為根節點的環。如果 y 點被訪問過,且還在棧中(說明這個點是強聯通分量的中的乙個點)繼續更新low值 low[ x ] = min(low[x], dfn[y]) 看誰出現的時間更早,不在棧中說明已經是其他或者自己成為了乙個強連通分量
回溯時 dfn [ x ] = low [ x ] 時 // x 這個點就是 強聯通分量的根,然後依次從棧內彈出元素,直到x == 棧頂元素(找到了環的根)就退出 找到了圖中的乙個強聯通分量
**:
const int maxn = 1e5 + 10;
struct edgeedge[maxn << 1];
int head[maxn], cnt, ans;
bool instack[maxn]; //判斷是否在棧中
//dfn 第一次訪問到該節點的時間(時間戳)
//low[i] low[i]能從哪個點(最早時間戳)到達這個點的。
int dfn[maxn], low[maxn], tot;
stackstc;
void add_edge(int u, int v, int dis)
void tarjan(int x) else if (instack[to])
} //cout << x << " " << low[x] << " " << dfn[x] << endl;
if(low[x] == dfn[x]) }}
void init()
int main ()
for(int i = 1; i <= n; ++i)
} return 0;
}
模板題:
hdu-1269
tarjan求強連通分量(模板)
include include include using namespace std const int maxn 50010 int pre maxn other maxn last maxn l intn,m intdfn maxn low maxn ans maxn st maxn belo...
模板 tarjan求強連通分量
大約是今年4月學的演算法了,後來5月的時候做題還寫了乙個退化的tarjanqaq。時間複雜度 o n m 用途 有向圖縮環 1 include 2 include3 include4 include5 include6 include7 include8 include9 include10 inc...
Tarjan模板 求強連通分量
tarjan求強連通分量的流程在這個部落格講的很清楚,再加上我也沒理解透,這裡就不寫了。縮點 將同乙個連通塊內的點視為同乙個點。扔一道模板題 codevs2822愛在心中 第一問很顯然就是求點數大於一的連通塊的個數,跑一次tarjan 第二問腦補一下發現,縮點後,若圖中有且僅有乙個點出度為0且為愛心...