bzoj1086 王室聯邦

2022-01-31 22:25:18 字數 1080 閱讀 9173

給出一棵樹,求一種分塊方案,使得每個塊的大小\(size\in [b,3b]\)。每個塊還要選乙個省會,省會可以在塊外,但是省會到塊內任何乙個點路徑上的所有除了省會的點都必須屬於這個塊。\(n\le 1000\)。

一次dfs即可解決。做法如下:

實現中有乙個問題,對於乙個兒子,它在棧中積累了不到\(b\)個點,而在下乙個搜尋的兒子的下層達到了\(b\)個點,那麼這樣兩個塊就會不連通,出現問題。所以我們每次設定乙個bottom,意為對於這個兒子它的棧底是**,這樣就可以保證不會彈出之前的節點,從而保證連通性。每次彈棧的時候把當前搜尋的節點設為省會,就一定能夠符合要求。最後搜尋完之後棧中會剩下一些節點,而這些節點必定與最後乙個塊連通,而最後乙個塊的節點個數和剩下的節點個數和\(sum\in (2b,3b]\),所以可以歸進同乙個塊內。**實現非常簡單。

這道題是樹分塊方法的模版題,樹分塊在很多樹上詢問問題中都有應用。

#include#include#include#includeint read() 

const int maxn=1e3+1;

int n,b,gs=0;

int sta[maxn],top=0;

int id[maxn],cap[maxn];

struct edge e[maxn<<1];

int h[maxn],tot=0;

void add(int u,int v) ;

h[u]=tot;

}void dfs(int x,int fa,int bot)

} sta[++top]=x;

}int main()

dfs(1,0,top);

while (top) id[sta[top--]]=gs;

printf("%d\n",gs);

for (int i=1;i<=n;++i) printf("%d ",id[i]);

puts("");

for (int i=1;i<=gs;++i) printf("%d ",cap[i]);

puts("");

return 0;

}

bzoj 1086 王室聯邦

餘 人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成員來管理。他的國家有n個城市,編號為1.n。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條直接或間接的道路。為了防止管理太過分散,每個省至少要有b個城市,為了能有效的管理,每個省最多只有3b個城...

BZOJ 1086 王室聯邦

思路 貪心,每次當儲存的兒子大於等於b時,分出乙個塊,這樣每次每個塊至多為2b,這樣剩下的沒有被分的塊小於b,可以加入任意乙個塊,都是合法的。1 include2 include3 include4 include5 include6 int tot,go 200005 first 200005 n...

王室聯邦(bzoj 1086)

餘 人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成 員來管理。他的國家有n個城市,編號為1.n。一些城市之間有道路相連,任意兩個不同的城市之間有且僅有一條 直接或間接的道路。為了防止管理太過分散,每個省至少要有b個城市,為了能有效的管理,每個省最多只有3b...