BZOJ 1086 SCOI2005 王室聯邦

2021-08-17 22:21:51 字數 1665 閱讀 4215

對一棵樹進行分塊。

dfs,找到了乙個節點,記錄乙個陣列st

s

t,代表它和它的子樹中,沒有被劃分進任何省的點。

首先對他的每個節點dfs,把它兒子的st

s

t序列加入自己的,如果自己st

s

t序列大於了

b b

,就把這所有的點都划進乙個省裡面,省會是當前dfs到的這個節點。

最後再把自己加入st

' role="presentation">sts

t序列中。

但是dfs完了之後,根節點的st

s

t序列還是沒有被劃分到任何乙個省中,這時,把它們划進最後乙個被新增的省中。

顯然,每個省必定會有多於

b b

個節點。

那麼如何證明每個點會少於3b

' role="presentation">3b3

b個節點呢?

考慮劃分省份的流程,dfs到了乙個點,它們的子樹必定:

1. 有乙個子樹最大,大小小於等於

b b

。 證明:如果這個最大的子樹大小大於

b' role="presentation">b

b,那麼在dfs這個子樹的根時,就已經產生了大小至少為

b b

而未分配省份的序列,不符合步驟要求。

2. 除了上述子樹,其餘子樹大小之和小於

b' role="presentation">bb。

證明:如果其餘的子樹大小之和大於等於

b b

,那麼在獲得最後乙個子樹前,其餘子樹已經達到了分配省份的標準。

所以有:除了最後乙個含有根的省份,乙個省份的大小必定小於等於2b

−1' role="presentation">2b−

12b−

1。 考慮最後剩餘的未分配的點,它們的大小必定小於等於

b b

,所以最後乙個省份大小必定小於3b

' role="presentation">3b3

b。

#include 

const

int maxn=1000;

int cap[maxn+10],stack[maxn+10],top,n,size,tot,cnt,belong[maxn+10];

int pre[maxn*2+10],now[maxn+10],son[maxn*2+10];

inline

int ins(int a,int b)

int dfs(int u,int fa)}}

j=pre[j];

}stack[++top]=u;

return0;}

int main()

dfs(1,0);

if(top)

}printf("%d\n",cnt);

for(register

int i=1; iprintf("%d ",belong[i]);

}printf("%d\n",belong[n]);

for(register

int i=1; iprintf("%d ",cap[i]);

}printf("%d\n",cap[cnt]);

return

0;}

bzoj1086 scoi2005 王室聯邦

題目鏈結 本來是來學樹上分塊的,沒想到正解是貪心 dfs。題意 求將樹分為幾個聯通塊,每個聯通塊大小大於b小於3b,是否可行。solution1 題都沒看就翻了題解。發現時貪心 dfs。一遍dfs即可。注意到以x為根節點時,其兒子s,則子樹s中與s相連的節點的連通塊,如果要構成乙個省,既可以s作為省...

bzoj1086 SCOI2005 王室聯邦

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

BZOJ 1086 SCOI2005 王室聯邦

啊啊啊啊啊啊啊啊啊啊啊啊 又是一道赤果果的水水模板題 沒辦法啊我太弱了。好吧 這是一道樹分塊 原題戳對其實你們依然不用戳 餘 人國的國王想重新編制他的國家。他想把他的國家劃分成若干個省,每個省都由他們王室聯邦的乙個成 員來管理。他的國家有n個城市,編號為1.n。一些城市之間有道路相連,任意兩個不同的...