《最小聯通塊》命題報告》學習筆記

2022-07-05 20:00:16 字數 2239 閱讀 7184

**搬運工++

loj提交位址

直接 \(o(n^2)\) 列舉 \(\\),然後再 \(o(n)\) 對於每個 \(w\) 判斷 \(w\) 是否在 \(u\to v\) 上,複雜度 \(o(n^3)\)

假設以 \(1\) 為根,那麼對於每乙個點 \(u\),我們可以通過 \(query(\,w)\) 詢問出它的祖先集合,那麼某個點的父親就是祖先集合包含於它的且集合最大的那個點,複雜度 \(o(n^2)\)。

首先我們考慮怎麼樣找到乙個點 \(u\) 任意乙個的子孫節點:假設目前可能的答案集合為 \(s\),每次得到乙個大小為 \(s\) 一半的集合 \(t\),\(query(\,u)\),如果 \(t\) 中存在答案,那麼令 \(s=t\),否則 \(s=s-t\)。其實就是乙個二分,單次尋找的複雜度為 \(o(\log n)\),如果還想找另外乙個就直接把當前找到的點去掉再找就好了。

我們考慮把整棵樹當做一顆內向樹,然後假定我們已經弄出這棵樹的任意乙個合法的拓撲序。

那麼我們可以按拓撲序從小往大掃瞄每個點,找到當前點的每個子孫節點並將這些點從點集中去掉,容易知道這樣的話除 \(1\) 外每個點只會被作為兒子節點找到一次,複雜度 \(o(n\log n)\)。

直接暴力把拓撲序找出來就是一層層剝葉子,每次去掉乙個點 \(u\) 看這個點還在不在 \(v-u\) 中,複雜度 \(o(n^2)\)。

注意此演算法中的利用拓撲序的思想,下面演算法均在 「找到拓撲序」 中展開。

注意到上面 1.3 每次找葉子的複雜度是 \(o(n)\) 的,我們想辦法優化找葉子的過程。

我們利用我們 1.3 中所講的找子孫節點的方法,每次找到任意乙個子孫並往下跳,跳不動了則找到了乙個葉子。

考慮這麼做的複雜度:乙個節點 \(u\) 子孫中大小超過 \(\lceil \frac \rceil\) 的節點最多佔到一半,所以我們期望跳兩次就可以使當前所在點的子樹大小減半,跳的期望次數是 \(o(\log n)\) 級別的,每次跳複雜度 \(o(\log n)\),所以總複雜度就是 \(o(n\log ^2n)\)。

還有一種剝葉子的方法就是考慮優化剝葉子的輪數。

考慮到如果我們當前這棵樹上沒有 \(2\) 度點,那麼總輪數就是 \(o(\log n)\) 級別的。

我們建出當前這棵樹的虛樹:即把乙個度數為 \(2\) 的點刪去,然後將該點相鄰的兩點連邊,遞迴執行此過程,留下的樹就是虛樹。

考慮如果我們每次可以剝掉虛樹上每個葉子和葉子所連的那條鏈上的所有點,我們可以保證複雜度。

考慮找出所有這樣的點,拿出葉子集合 \(l\),然後每次 \(2\log n\) 找當前點集裡只存在乙個葉子的點,這樣可以找到很多條鏈,再將每條鏈從上到下排好序即可。

最後的複雜度是 \(o(n\log ^2n)\)。

我們現在考慮從分治的角度入手。

假設當前在點 \(x\),我們隨機找到其子樹內的乙個點 \(y\),我們確定 \(y\) 子樹內的點集後,可以將 \(x\) 的子樹劃分為 \(2\) 個部分,繼續遞迴執行操作。

如果像平常點分治那麼做複雜度顯然假假,我們考慮將 \(y\) 刪去後所有聯通塊染成了若干種不同的顏色。

我們的目的就是判斷每個點是否為白色。

考慮將所有點按編號拍成一行:

那麼我們可以確定每個極長顏色段的分割點,確定完之後和 \(1\) 查詢就可以知道每個段是否是白色的了,然後每次確定乙個極長的連續段利用二分是 \(o(\log n)\) 的。

整個演算法的複雜度的話考慮出現次數最多的顏色,可以發現顏色總段數是 \(o(n\log n)\) 級別的,具體的這裡我不想寫了。。然後演算法總複雜度就是 \(o(n\log ^2n)\)。

事實上我們並不需要知道每個點子樹外的點是什麼,只需要得到一種合法的拓撲序就好了。

那麼我們可以任意選擇當前節點 \(u\) 子樹中的乙個點 \(v\),在得到 \(v\) 中的點後將 \(v\) 中的點按原先排好的拓撲序加入當前拓撲序的末尾,對 \(v\) 同樣地處理就好了,複雜度 \(o(n\log n)\)。

我們實際上不需要在樹上做這件事,只需要加入節點時時刻保證當前維護的拓撲序合法即可。

那麼我們可以每次加入乙個點,它需要保證所有祖先出現在它後面,所有子孫出現在它前面,這個過程可以二分,複雜度\(o(n\log n)\)。為什麼複雜度低的演算法看起來還簡單些啊

**實現去 loj 找吧,這裡就不放了。

學習記錄 BFS的聯通塊與計步

1 include 2 using namespace std 3struct node 7 queueq 8const int maxn 200 9 intmaap maxn maxn 10bool book maxn maxn 11int m,n 12int next 4 2 18void bf...

學習記錄 DFS的聯通塊與計數 剪枝

1 include 2 using namespace std 3const int maxn 1000 4 intn,m 5 地圖尺寸 6int maap maxn 10 maxn 10 7 查詢零一地圖中的1聯通塊個數 8bool vis maxn 10 maxn 10 9 int direx ...

log4j聯通ELK學習筆記

springboot logback log4j配置 log輸出到elk spring boot 日誌篇 log4j整合elk,搭建實時日誌平台 spring boot 日誌篇 log4j整合elk,搭建實時日誌平台 elk日誌處理之使用logstash收集log4j日誌 搭建elk elastic...