無向圖中的雙連通分量有兩種:點雙連通分量和邊的連聯通分量,如果去掉任意乙個點之後,這個圖還是連通的,就說這個圖是點雙連通的。如果去掉任意一條邊之後這個圖還是連通的,就說明這個圖是邊雙連通的。
割橋將每乙個邊-雙連通分量分開,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被稱為 割點 簡單的說,在雙連通圖中,任何一對頂點都至少存在兩條路徑可以互相到達。圖的連通 性不會任何乙個頂點的影響。這個性質具有許多重要的應用...
雙連通分量
雙連通分量就是無向圖中的強連通分量,基本就是找割頂和橋。割頂就是乙個點,如果把它取掉,連通分量數量就會增加,橋就是一條邊,同理。對於乙個連通圖,如果任意兩點至少存在兩條 點不重複 的路徑,也就是任意兩條邊都在乙個簡單環中,即內部無割頂,則說這個圖是點雙連通的。對於乙個連通圖,如果任意兩點至少存在兩條...