拿來學了一下樹分塊。
樹分塊的要求是把樹分成⌈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 餘 人國的國王想...