若您是第一次了解\(tarjan\)演算法,建議您反覆閱讀定義,借助影象來理解
對於無向連通圖中點集的乙個節點\(x\),刪去節點\(x\)及其關聯的邊之後,存在一對不聯通的點對\((a,b)\),則稱\(x\)是這個無向圖的割點
對於無向聯通圖中邊集的一條邊\(e\),刪去邊\(e\)之後,存在一對不聯通的點對\((a,b)\),則稱\(x\)是這個無向圖的橋或割邊
對於一般無向圖,割點和橋可以指各個聯通塊的割點和橋
在對圖的\(dfs\)中,按照節點第一次被訪問的順序,給各個節點標記乙個值,該值稱為時間戳,我們用\(dfn[x]\)表示\(x\)的時間戳
在對圖的\(dfs\)中,由於每個點只會被搜一次,所以訪問經過的邊構成了一棵樹,稱為搜尋樹,各個節點為根的子樹稱為\(subtree(x)\),注意,\(x \in subtree(x)\)
這個可以說是\(tarjan\)演算法的精髓了,在我個人看來,節點\(x\)的追溯值是指不經搜尋樹所能到達的所有節點中其時間戳的最小值或者它自身的時間戳.
這看起來很難得到各個節點的追溯值,實則不然,分析一下,節點\(x\)的追溯值可以在一遍\(dfs\)中求得,請看下文介紹
更新\(low[x]\)
根據定義,我們只能用\(x\)在搜尋樹上兒子的\(low\)值或是一條非搜尋樹邊\((x,y)\)中的\(dfn[y]\)來更新\(low[x]\)
重邊在求橋時,若節點\(x\)與其父親間有重邊,則其中只有一條算搜尋樹上的邊,其他都是非搜尋樹上的邊,可以用來更新.
然而求割點時,由於是點與點聯通關係不必考慮重邊
int dfn[maxn],low[maxn],cnt=0;
bool bridge[maxm];
void tarjan(int u,int in_edge)
}else if(i!=(in_edge^1))
}return ;
}
int dfn[maxn],low[maxn],root,tot=0;
bool ans[maxn];
void tarjan(int now)}}
else low[now]=min(low[now],dfn[v]);
}return ;
}
學習筆記 割點 tarjan
給出乙個n個點,m條邊的無向圖,求圖的割點。那麼割點是什麼呢,就是說,如果你去掉了這個點和所有與這個點相連的邊之後,整張圖的連通塊數量增加了,這個點就是乙個割點 怎麼做呢,每次列舉乙個點,dfs一遍,看有沒有增加連通塊,好像是n方,n有2w那麼大,會炸啊 運用這個演算法,可以只dfs一遍,或者只需要...
學習筆記 tarjan求割點
都口胡了 求割邊,就順便口胡 求割點好了qaq 的定義同 求有向圖強連通分量.列舉當前點 的所有鄰接點 1.如果某個鄰接點 未被訪問過,則訪問 並在回溯後更新 2.如果某個鄰接點 已被訪問過,則更新 對於當前節點 如果 為搜尋樹中的根節點,若它的子節點數 根是多棵子樹上節點的唯一連通方式 則 為割點...
《學習筆記》 tarjan 求割點(割頂)
go to the problem 割點 在乙個無向圖中,如果有乙個頂點集合,刪除這個頂點集合以及這個集合中所有頂點相關聯的邊以後,圖的連通分量增多,就稱這個點集為割點集合。如果某個割點集合只含有乙個頂點x 也即是乙個割點集合 那麼x稱為乙個割點。割點 給出乙個n個點,m條邊的無向圖,求圖的割點。輸...