爆棧指遞歸中,存儲的信息量大於系統棧的內存。
信息量包括元素編號,每一層中開的變量。
和遞歸的層數正相關。
(雖然noip一般開棧)
1.手寫棧
while(top){
int x=sta[top];
for(each son)
if(has son){
//blablabla
sta[++top]=son;
hd[x]=e[i].nxt;
}
else{
//blablabla
sta[top--]=0;
}
}
可以用一個弧優化,使得每次兒子回溯后,父親往下的邊的訪問直接繼續。
這樣復雜度就對了。
如果son回溯后,在到下一個son之前,還要做一些事情,那就用個pair,結構體什么的,討論一下情況即可。
2.bfs序求dfs序
用bfs求dfs序(先序遍歷序)
相同點:
先出來father的編號再出來son的編號。根節點都是1號。
區別:子樹連續訪問pk兒子連續訪問。
聯系:就差一個size
bfs求bfs序,再倒序記錄每個點的size
然后,遍歷bfs序。
這時x的fa一定已經求出了dfs序。
如果上一個點的fa和這個點的fa不同,那么x一定是x的fa的第一個兒子,到了fa之后就先訪問x。dfn[x]=dfn[fa[x]]+1
如果上一個點的fa和這個點的fa相同,那么x一定是上一個點的后兄弟。dfn[x]=dfn[las]+size[las]
理解就是,dfs時會先遍歷las的整個子樹。並且下一個就一定是x了。
3.本地手動開棧:
#pragma GCC ("-W1,--stack=128000000)手動開棧。