邊雙連通分支

2021-08-04 17:05:41 字數 1323 閱讀 4450

/*

求邊雙連通分支:跑一遍求割點與橋的tarjan得到該圖的割點和橋,去掉橋,其餘連通分支就是邊連通分支了,邊連通分支數是橋數+1。

邊連通分支就是去掉最少兩條邊才能將該圖劃分為兩個部分的圖,橋就是乙個圖被去掉一條邊就能變成兩個子圖的那一條邊,

構造邊雙連通分支:

把雙連通子圖收縮為乙個點,形成乙個樹,需要加邊數量是(leaf+1)/ 2 。即不斷把最近公共祖先最遠的兩個葉節點連線一條邊

*///poj3177

#include

#include

#include

#include

#include

using

namespace

std ;

const

int maxn = 5000 + 10 ;

const

int maxm = 20000 + 10 ;

struct edgeedge[maxm];

int head[maxn] , tot ;

//low[u]表示u所能追溯到的在棧中最早的節點,該low陣列和求割點與橋的low陣列定義不一樣

int low[maxn] , dfn[maxn] , stack[maxn] , belong[maxn] ;

int index , top ;

//邊雙連通塊數

int block ;

bool instack[maxn] ;

//橋的數目

int bridge ;

void addedge( int u , int v)

void tarjan( int u , int pre)

}//(u,v)回向邊,修改u所能追溯到的編號最小的節點

else

if( instack[v] && low[u] > dfn[v])

low[u] = dfn[v] ;

}//u節點是該連通分量的根節點

if( low[u] == dfn[u])

while( v != u ) ;

}}void ini()

//縮點後形成樹,每個點的度數

int du[maxn] ;

void solve( int n )

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

if( du [i] == 1)

ans ++;

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

}int main()

solve( n ) ;

}}

強連通分支

1。定義 有向圖強連通分量 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 現在來...

邊雙連通分量還有橋

我發現了兩種邊雙的寫法 1.先求橋,標記橋再dfs求連通塊,似乎有點麻煩 2.直接上有向圖的寫法,把回頭的情況標記一下 其1int tarjan int x,int fa else if fa 1 i fa 1 return 0 int dfss int x return 0 scanf d lld...

tarjan演算法求強連通分支

近期做資料結構課程設計,遇到了有向圖的強連通分支的問題,網上採用的是基於深度優先遍歷的tarjan演算法,在考了許多部落格後,還是有些迷,在思考了一番後,終於明白了,所以寫了這篇文章。首先,明確以下幾點。tarjan演算法基於深度優先遍歷。使用時,會用到兩個棧。乙個棧用於dfs,如果是遞迴的tarj...