/*
求邊雙連通分支:跑一遍求割點與橋的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...