scoi2005 王室聯邦 解題報告

2021-07-11 05:17:51 字數 1276 閱讀 7055

拿來學了一下樹分塊。

樹分塊的要求是把樹分成⌈n

b⌉塊,每一塊的每個節點到這個塊的lca的之間的節點數不超過3b

. (好像在很久以前聽誰講過。。)做法是按dfs序出棧或bfs倒序考慮,把當前這個子樹的剩餘塊加到它的父親上,如果它的父親上的塊已經≥b

就把這個塊取出來。這樣的話出來的就是若干大小在[b,2b)的塊加上乙個在[0,b)的塊,注意到按dfs或bfs序考慮時,倒數第二個塊與最後乙個塊一定是聯通的,所以可以把它們倆並起來,這樣大小就在[0,3b)了。

#include

#include

using namespace std;

#include

#include

const int n=1000+5,b=1000+5;

intnext[n<<1],succ[n<<1],ptr[n],etot=1;

void addedge(int from,int to)

int capital[n],bnum[n],btot=1;

int size[n];

int fa[n];

vector son[n];

int treeq[n],blockq[n];

int main()

treeq[0]=1;

for(int h=0,t=1;h!=t;++h)

for(int i=ptr[treeq[h]];i;i=next[i])

if(succ[i]!=fa[treeq[h]])

for(int h=n;h--;)

//printf("capital(%d)=%d\n",btot,fa[treeq[h]]);

capital[btot++]=max(fa[treeq[h]],1);

size[fa[treeq[h]]]=0;

son[fa[treeq[h]]].clear();}}

blockq[0]=0;

--btot;

for(int h=0,t=1;h!=t;++h)

for(int i=son[blockq[h]].size();i--;)

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

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

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

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

printf("%d\n",capital[btot]);

}

SCOI2005 王室聯邦

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

SCOI2005 王室聯邦

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

SCOI 2005 王室聯邦 樹上分塊?

在wzh大神 ps 我是渣渣wzh 的部落格看見的乙個分塊題目,剛好要複習分塊,於是我就研究了一下樹上分塊,恩,這個題目的要求和樹上分塊差不多。沒什麼就是原來的size變成題目規定的b了,然後這就變成了分塊的模板題目。bzoj 大神wzh的部落格orzwzh description 餘 人國的國王想...