SDUT 2798 小鑫的城堡(並查集應用)

2021-08-24 20:32:23 字數 1655 閱讀 4597

從前有乙個國王,他叫小鑫。有一天,他想建一座城堡,於是,設計師給他設計了好多簡易圖紙,主要是房間的連通的圖紙。小鑫希望任意兩個房間有且僅有一條路徑可以相通。小鑫現在把設計圖給你,讓你幫忙判斷設計圖是否符合他的想法。比如下面的例子,第乙個是符合條件的,但是,第二個不符合,因為從5到4有兩條路徑(5-3-4和5-6-4)。

input

多組輸入,每組第一行包含乙個整數m(m < 100000),接下來m行,每行兩個整數,表示了一條通道連線的兩個房間的編號。房間的編號至少為1,且不超過100000。

output

每組資料輸出一行,如果該城堡符合小鑫的想法,那麼輸出」yes」,否則輸出」no」。

sample input

5 2 5

2 3

1 3

3 6

4 6

6 1 2

1 3

3 4

3 5

5 6

6 4

sample output

yes

no這個題目有幾個地方需要注意一下,只要注意到這幾個地方就很容易了,圖中任意的兩點之間只有一條路,所以很自然的,我們想到圖應該是構成一棵樹,那麼,判斷條件就是邊的數目 = 點的數目 - 1,這個在實現上,因為輸入不同的邊會有重複的點,所以可以使用乙個陣列來進行標記,標記下已經輸入的點,這樣統計這個陣列就可以得到點的數目了,但是只有這乙個條件是不對的,題目中並沒有指明圖是否連通,所以符合這個條件的還有這樣的非連通圖:

所以要繼續對條件進行篩查,既然是圖的連通影響了條件,所以,我們再加乙個圖的連通的判斷條件,使用並查集的方式很簡單就可以判斷。所以,我們可以得到最後的判斷條件就是圖連通 && 邊數 = 點數- 1

**如下:

#include

#include

#include

#include

#define n 100005

using

namespace

std;

int tree[n]; // 並查集用來標記每個節點的父節點的陣列

int mark[n]; // 標記節點是否已經重複輸入的陣列

int m;

int cou; // 計數節點的數量

int a,b;

int findroot(int x)

}int main()

int res = 0;

for(int i=0; i// 如果某乙個節點對應的陣列的值是-1 那麼這個點就是根節點(一開始我初始化整個陣列為-1)

if(tree[i]==-1 && mark[i]) //注意也要判斷mark[i] 防止題目的節點標號不連續

res++; //記錄有多少個根節點(連通子圖)

}if(res==1 && m==cou-1) //根節點只有乙個表示圖是連通的 邊數 = 節點數-1 表示是樹

cout

<

cout

<

以上~

SDUT2798 小鑫的城堡(並查集)

time limit 1000ms memory limit 65536kb submit statistic discuss problem description 從前有乙個國王,他叫小鑫。有一天,他想建一座城堡,於是,設計師給他設計了好多簡易圖紙,主要是房間的連通的圖紙。小鑫希望任意兩個房間有...

並查集 小鑫的城堡

time limit 1000ms memory limit 65536k 從前有乙個國王,他叫小鑫。有一天,他想建一座城堡,於是,設計師給他設計了好多簡易圖紙,主要是房間的連通的圖紙。小鑫希望任意兩個房間有且僅有一條路徑可以相通。小鑫現在把設計圖給你,讓你幫忙判斷設計圖是否符合他的想法。比如下面的...

小鑫的城堡(並查集)

time limit 1000ms memory limit 65536k 有疑問?點這裡 從前有乙個國王,他叫小鑫。有一天,他想建一座城堡,於是,設計師給他設計了好多簡易圖紙,主要是房間的連通的圖紙。小鑫希望任意兩個房間有且僅有一條路徑可以相通。小鑫現在把設計圖給你,讓你幫忙判斷設計圖是否符合他的...