HDU 3394 Railway(點雙連通分量)

2021-07-16 02:06:33 字數 1764 閱讀 4962

description

給乙個無向圖,如果至少有兩個環共用了一些邊,那麼這些邊被認為是衝突邊,如果一些邊不在任何乙個環中,這些邊被認為是多餘邊,問這個圖中有多少多餘邊和衝突邊

input

多組用例,每組用例第一行為兩個整數n和m表示該無向圖的點數和邊數,之後m行每行兩個整數u,v表示u和v之間有一條無向邊,以0 0結束輸入

output

對於每組用例,輸出多餘邊和衝突邊的數量

sample input

8 10

0 1

1 2

2 3

3 0

3 4

4 5

5 6

6 7

7 4

5 7

0 0

sample output

1 5

solution

顯然多餘邊就是橋,而對於衝突邊,其必然在點雙連通分量中出現,如果乙個塊的點數等於邊數,說明其是乙個環,沒有衝突邊,但如果邊數大於點數,說明這個塊裡至少有兩個環,簡單分析知此時塊內所有邊均為衝突邊,所以問題轉變為求橋的數量以及每個塊的點數和邊數,用tarjan求點雙連通分量,順便就可以求出橋數,每找到乙個塊,就統計塊內點的數量以及這些點之間連的邊數,判斷邊數是否大於點數,如果大於則將邊數累加到答案中

code

#include

#include

#include

#include

#include

using

namespace

std;

#define maxn 11111

#define maxm 222222

struct edge

edge[maxm];

int head[maxn],tot;

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

int index,top;

int block;//點雙連通分量的個數

int bridge;//橋的數量

bool instack[maxn];

vector

vec;

int flag[maxn];

int ans;

void add_edge(int u,int v)

void count()

count/=2;

if(count>vec.size())ans+=count;

}void tarjan(int u,int pre)

while(vn!=v);

belong[u]=block;

vec.push_back(u);

count(); }}

else

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

low[u]=dfn[v];

}}void solve(int n)

void init()

int n,m;

int main()

ans=0;

solve(n);

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

}return

0;}

HDU3394 Railway 點雙連通分量

題意 給出乙個無向圖,求出它的衝突邊數和多餘邊數,衝突邊就是那些同時存在於多個環中的邊,而多餘邊是不在任何乙個環中的邊.要點 多餘邊很明顯就是橋,我們可以推斷除衝突邊只能在點雙連通分量中,感覺邊雙應該也行,主要就是求出分量後看分量中點數n和邊數m的關係,如果n include include inc...

HDU 3394 Railway 點雙連通分量

題意 給定乙個無向圖,找出不在任意乙個環上的邊數和同時在多個環上的邊數。思路點 雙連通分量如果在邊數等於點數,那麼形成乙個環,邊數多於點數,說明環中有多條邊。include include include include include include include include include...

hdu3394Railway 雙連通分量

題目描述 給出一張無向圖,分別求出圖中滿足如下兩種條件的邊的數量 1 該邊不在任何簡單環當中 2 該邊在多個簡單環當中 方法 不在任何簡單環當中的,就是圖中的橋,可以求出來 通過簡單環聯想到點雙連通分量,找到某個雙連通分量,若該雙連通分量包含的邊數超過該點雙連通分量包含的點數,那麼這個雙 連通分量中...