雙連通分量

2021-08-08 22:52:46 字數 2742 閱讀 9443

無向圖中的雙連通分量有兩種:點雙連通分量和邊的連聯通分量,如果去掉任意乙個點之後,這個圖還是連通的,就說這個圖是點雙連通的。如果去掉任意一條邊之後這個圖還是連通的,就說明這個圖是邊雙連通的。

割橋將每乙個邊-雙連通分量分開,low[i]的意義就是low[i]所連的塊能返回的最早的祖先,也就是說,low[i]相同的點即為乙個邊連通分量。

tips

//點-雙連通分量

const int maxn=5000+10;//點數

struct edge

};int pre[maxn]; //第一次訪問的dfs_clock時間戳

int low[maxn];

int iscut[maxn]; //割點判斷

int bccno[maxn]; // bccno[i]表示i所在最早訪問的點-雙聯通分量的下標 即bcc[bccno[i]]這個連通分量集合中含有i這個點 對於割頂來講沒有意義,因為他屬於多個點-雙聯通分量

vectorbelong[maxn];//belong[i]表示i所在的雙連通分量的下標的集合

int dfs_clock;

int bcc_cnt; // 雙連通分量個數

vectorg[maxn]; // 頂點,下標0~n-1

vectorbcc[maxn]; //點雙連通分量儲存結果 下標1~bcnt

stacks;

int dfs(int u,int fa)

if (bccno[x.v] != bcc_cnt)

if (x.u == u && x.v ==v) }}

}else if(pre[v] < pre[u] && v != fa)

}if (fa < 0 && child == 1)

return low[u]=lowu;

}int find_bcc(int n)

}return cnt;

}void work(int n,int m)

for (int i=0; i#include #include using namespace std;

#define mem(a) memset(a, 0, sizeof(a))

#define pb push_back

const int maxv = 1010;

int pre[maxv], low[maxv], deg[maxv], stakk[maxv];

int dfs_clock, top;

vectorg[maxv];

void dfs(int u, int fa) else if (pre[v] < pre[u] && v != fa)

}if (pre[u] == low[u])

}}void find_bcc(int n)

int main()

find_bcc(n);

int ans = 0;

for (int i = 1; i <= n; i++) }}

for (int i = 1; i <= n; i++)

if (deg[i]/2 == 1) ans++;

printf("%d\n", (ans+1)/2);

}

return 0;}/*

la 3523 knights of the round table

亞瑟王要給一些騎士開會,但是這些騎士中有一些相互憎恨,

所以他們不能在圓桌中相鄰,為了投票不出現支援的人數和反對的人數相等的情況,

每個圓桌中的騎士的個數必須為奇數個,

問有多少個騎士一定不能參加任何乙個會議。

因為可能要開好幾桌會議,所以要求出圖中所有的連通分量,

又因為要求騎士的個數為奇數個,所以求每個聯通分量中不在奇圈上的點的個數的和

*/#include #include #include #include using namespace std;

#define mem(a) memset(a, 0, sizeof(a))

const int maxv = 1100;

const int maxe = maxv*maxv;

vectorg[maxv], bcc[maxv];

int dfs_clock, bcc_cnt, pre[maxv], low[maxv], bccno[maxv];

struct edge

edge(int a, int b)

};stacks;

bool bipartite (int u, int b)

}return true;

}void tarjan(int u, int fa)

if (bccno[x.v] != bcc_cnt)

if (x.u == u && x.v == v) break;}}

}else if (pre[v] < pre[u] && v != fa)

}}void find_bcc(int n)

int main()

for (int u = 1; u <= n; u++) }}

find_bcc(n);

mem(odd);

for (int i = 1; i <= bcc_cnt; i++)

int ans = n;

for (int i = 1; i <= n; i++) if (odd[i]) ans--;

printf("%d\n", ans);

}return 0;

}

雙連通分量

在無向連通圖中,如果刪除該圖的任何乙個結點都不能改變該圖的連通性,則稱該圖是雙連通的。雙連通無向圖一定是連通的,而連通的無向圖則不一定是雙連通的。對於乙個連通的無向圖也有雙連通分量的概念,定義自然不言而喻。同樣,我們也可以利用tarjan演算法求雙連通分量。define n 10000 struct...

雙連通分量

在乙個無向連通圖中,如果任意去掉乙個定點i及依附於i的所有邊後得到的圖仍然連通,則稱該圖為 2 連通圖 否則,若得到多個連通分量,則該圖不是雙連通的,頂點i被稱為 割點 簡單的說,在雙連通圖中,任何一對頂點都至少存在兩條路徑可以互相到達。圖的連通 性不會任何乙個頂點的影響。這個性質具有許多重要的應用...

雙連通分量

雙連通分量就是無向圖中的強連通分量,基本就是找割頂和橋。割頂就是乙個點,如果把它取掉,連通分量數量就會增加,橋就是一條邊,同理。對於乙個連通圖,如果任意兩點至少存在兩條 點不重複 的路徑,也就是任意兩條邊都在乙個簡單環中,即內部無割頂,則說這個圖是點雙連通的。對於乙個連通圖,如果任意兩點至少存在兩條...