P2325 SCOI2005 王室聯邦 解題報告

2022-04-29 23:09:08 字數 1229 閱讀 1854

「餘」人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成員來管理。

他的國家有\(n\)個城市,編號為\(1\dots n\)。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條直接或間接的道路。為了防止管理太過分散,每個省至少要有\(b\)個城市,為了能有效的管理,每個省最多只有\(3b\)個城市。

每個省必須有乙個省會,這個省會可以位於省內,也可以在該省外。但是該省的任意乙個城市到達省會所經過的道路上的城市(除了最後乙個城市,即該省省會)都必須屬於該省。

乙個城市可以作為多個省的省會。

聰明的你快幫幫這個國王吧!

第一行包含兩個數\(n\),\(b\)(\(1\le n\le 1000, 1\le b \le n\))。接下來\(n-1\)行,每行描述一條邊,包含兩個數,即這條邊連線的兩個城市的編號。

如果無法滿足國王的要求,輸出\(0\)。

否則第一行輸出數\(k\),表示你給出的劃分方案中省的個數,編號為\(1\dots k\)。

第二行輸出\(n\)個數,第\(i\)個數表示編號為\(i\)的城市屬於的省的編號。

第三行輸出\(k\)個數,表示這\(k\)個省的省會的城市編號,如果有多種方案,你可以輸出任意一種。

這裡扔乙個偷來的,順便問下這是哪個ppt呀

一種樹分塊的方法...我還不知道這東西的實際意義

記錄當前點的棧頂,然後每遍歷完乙個兒子,如果棧頂-記錄點的個數大於\(b\),就以這個點為首都扔出來,最後把這個點加進去。

如果最後有剩,放到最後乙個點形成的首都裡就行了,可以證明不超過\(3b\)

code:

#include const int n=1e3+10;

int head[n],to[n<<1],next[n<<1],cnt;

int n,b,s[n],rt[n],bel[n],tot,top;

void add(int u,int v)

void dfs(int now,int fa)

}s[++top]=now;

}int main()

{ scanf("%d%d",&n,&b);

for(int u,v,i=1;i2019.1.6

P2325 SCOI2005 王室聯邦

傳送門 一遍dfs,如果某個子樹的未劃分的個數大於等於 b 那麼就把他們單獨劃為乙個省,該點作為省會 最後把所有剩下的和 1 劃到乙個省就好了 minamoto include define r register define fp i,a,b for r int i a,i b 1 ii i de...

P2325 SCOI2005 王室聯邦

利用了樹上莫隊的分塊方式,保證每個塊的大小都 ge b且 le 3b,然後證明略過 僅敘述一下演算法的過程 使用乙個棧,依次dfs這個點的每個子樹,如果發現新增的節點數大於等於b,就分出新的一塊,最後把剩下的節點塞進最後乙個塊裡 分塊的 void dfs int u,int f s.push u i...

SCOI2005 王室聯邦

這一篇類似是強聯通的東東大家參考一下吧,我也不會講這題。大家可以傳送去我同學那裡看看的qaq傳送門 提交傳送門 題目描述 餘 人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成員來管理。他的國家有n個城市,編號為1.n。一些城市之間有道路相連,任意兩個不同的城...