noip最後一次學習+敲板子
橋:如果這條邊去掉後圖的聯通分量增加,則這條邊稱為橋。
邊雙聯通分量:如果乙個對於乙個圖的某個子圖,任意兩點至少存在兩條「邊不重複」的路徑,則這個子圖是邊雙聯通分量。
很顯然,任意乙個邊雙中不含有橋。
除橋外每條邊都僅屬於乙個邊雙。如果把原圖中所有橋刪除,每個聯通分量都是原圖中的乙個邊雙。邊雙之間不存在公共節點。
求邊雙的做法是兩次dfs,第一次先找出原圖中所有的橋。由於邊雙不含有公共節點,所以第二次遍歷,不要經過橋即可。
重點就在於找橋。記錄d
fn[x
] dfn
[x
]為x入棧的時間戳,lo
w[x]
l ow
[x
]為x可達的所有點中最小的df
n[so
n[j]
] dfn
[son
[j]]
那麼如果邊(x
,y) (x,
y)
滿足lo
w[y]
>df
n[x]
l ow
[y
]>df
n[x]
,那麼這條邊為橋。
模板 hihocoder 1184
裸題求邊雙。
#include
#include
#include
using
namespace
std;
int n,e,tot,lnk[20005],nxt[200005],son[200005],dfn[20005],low[20005],id[20005],idmin[20005];
bool vs[200005];
inline
char nc()
inline
void readi(int &x)
}void _add(int x,int y)
void _dfsa(int x,int fa)else
if (son[j]!=fa) low[x]=min(low[x],dfn[son[j]]);
}void _dfsb(int x)
int main()
tot=0;
memset(vs,1,sizeof(vs));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
for (int i=1;i<=n;i++)
if (!dfn[i]) _dfsa(i,0);
tot=0;
memset(id,0,sizeof(id));
memset(idmin,63,sizeof(idmin));
for (int i=1;i<=n;i++)
if (!id[i])
printf("%d\n",tot);
for (int i=1;i<=n;i++) printf("%d ",idmin[id[i]]);
return
0;}
邊雙聯通分量
首先什麼是邊雙聯通分量?邊雙連通分量是指,在 無向圖 中刪除任意一條邊依舊聯通的聯通塊 之前講過強連通分量,這裡邊雙聯通分量的做法也需要利用tarjan演算法獲得邊雙聯通分量。對於邊雙聯通分量中還有乙個概念,就是橋。橋指的是 刪除該邊圖不再連通。對應的另乙個概念是 割點 割點的的是 如果除去此節點和...
邊雙聯通分量與割邊
在圖論中,除了在有向圖中的強連通分量,在無向圖中還有一類雙聯通分量 雙聯通分量一般是指點雙連通分量 當然,還有一種叫做邊雙連通分量 對於乙個連通圖,如果任意兩點至少存在兩條 邊不重複 的路徑,則說圖是點雙連通的,邊雙連通的極大子圖稱為邊雙連通分量。邊雙聯通分量的計算方法比較簡單 模擬tarjan求強...
邊雙聯通分量與割邊
在圖論中,除了在有向圖中的強連通分量,在無向圖中還有一類雙聯通分量 雙聯通分量一般是指點雙連通分量 當然,還有一種叫做邊雙連通分量 對於乙個連通圖,如果任意兩點至少存在兩條 邊不重複 的路徑,則說圖是點雙連通的,邊雙連通的極大子圖稱為邊雙連通分量。邊雙聯通分量的計算方法比較簡單 模擬tarjan求強...