杭電3367 並差集

2021-09-24 07:58:02 字數 1848 閱讀 1945

杭電3367傳送門

寫在題前:

這個題剛開始理解錯了,本來以為:最終的結果只能有乙個迴圈,後來wa了!唉,說多了都是眼淚。

注意、注意、注意,這不是最大生成樹什麼亂七八糟的!!!

根據題目的意思,乙個堆裡只能有乙個環,最後的結果可以是多個堆,因此可以有多個環(每個環都分布在不同的堆)。

解題思路:

借助貪心的思想。

將輸入的資料存起來,然後按照權值從大到小的順序,將資料進行排序。

遍歷資料,判斷能否進行建立關係。

用乙個累加器ans記錄答案,能建立關係的,就更新ans的值。

遍歷之後,ans就是答案。(其實並沒有帶權並差集什麼事)

判斷每組資料能否建立關係:

vis陣列用來標記該節點所在的堆是否有環。

兩個節點代表的堆要建立關係,有兩種可能:

兩個節點本來就在同乙個堆裡面

這個時候判斷這個堆裡面有沒有環,如果有的話,就不用建立關係

如果沒有的話,除了建立關係,還需要將這個堆標記成有環的狀態

兩個節點代表不同的堆,這個時候又分為三種情況:

1、兩個堆都有環:這個時候就不用建立關係。

2、其中只有乙個堆有環,另乙個無環:建立關係,還需要標記有環。

3、兩個堆都沒有環:只需建立關係即可。

寫在題後:

ac**

# include

# include

# include

# include

# include

# include

# include

# include

using namespace std;

typedef

long

long ll;

const

int maxn =

1e5+

100;

int id[maxn]

;int vis[maxn]

;//標記是否有環

struct node

;//一組資料

intfin

(int x)

bool meg

(int x,

int y)

else

vis[a]

+= vis[b]

;//更新vis標記。

return true;

//這個函式按照講解的過程寫也行,都是乙個意思。

}bool same

(int x,

int y)

bool cmp

(node a, node b)

intmain()

for(

int i =

0; i < n +

10; i++

)memset

(vis,0,

sizeof

(vis));

//注意初始化

vector s;

for(

int i =

0; i < m; i++

)sort

(s.begin()

, s.

end(

), cmp)

;int ans =0;

for(

int i =

0; i < s.

size()

; i++)}

else}}

cout << ans << endl;

}return0;

}

杭電1272 並差集

原題傳送門,並差集模板詳解鏈結,大佬並差集詳解鏈結。解題思路 1 判斷是否有環 2 判斷所有的房子是否連在一起。第一點可以通過same函式判斷,在輸入的時候就可以判斷 第二點可以先通過vis陣列標記,然後遍歷vis陣列,當vis i 1並且id i i的時候,說明i是最上面的父親。再符合條件的情況下...

杭電1198 並差集

原題傳送門,並差集模板函式簡單介紹,大佬的並差集詳解。寫在題前 因為最近學的並差集,因此專門搜的杭電並差集,也就是說,在看這個題之前我已經知道他是用並差集來做的。之前我碰到的題沒有涉及到二維這種情況,其實了解了思路還是很好做的,就是過程有點繁瑣,細節要注意。解題步驟 1 遍歷每個田地,對於每個田地,...

杭電1598 並差集

寫在題前 解題思路 將輸入的資料,按照速度的大小 從小到大 排序 依次將資料用meg函式建立關係,判斷查詢的資料是否符合 第一次符合條件的速度減去剛開始的速度就是答案。具體見 寫在題後 ac include include include include include include includ...