樹
實作練習
樹鏈剖分
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1E5+10;
vector<int> G[MAXN];
int cnt=0, sz[MAXN], link[MAXN], big[MAXN], dep[MAXN], fa[MAXN], arr[MAXN];
//link[x] = 所屬樹鏈的頂端, big[x] = 最大的子節點, arr[x] = 壓平序列的編號
void dfs(int x, int f){
sz[x]=1;
fa[x]=f;
big[x]=-1;
dep[x]=dep[f]+1;
for(int i:G[x]){
if(i==f) continue;
dfs(i,x);
sz[x]+=sz[i];
if(big[x]==-1||sz[i]>sz[big[x]]){
big[x]=i;
}
}
}
void getlink(int x, int top){
link[x]=top;
arr[x]=cnt++;
if(big[x]!=-1) getlink(big[x],top);
for(int i:G[x]){
if(i==fa[x]||i==big[x]) continue;
getlink(i,i);
}
}
重心剖分
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1E5+10;
vector<int> G[MAXN];
int sz[MAXN], centree[MAXN];
//centree[x] = 重心樹上的父節點
bool visited[MAXN];
void getsz(int x, int f){
sz[x]=1;
for(int i:G[x]){
if(visited[i]||i==f) continue;
getsz(i,x);
sz[x]+=sz[i];
}
}
int findcentroid(int x, int f, int s){
for(int i:G[x]){
if(2*sz[i]>=s&&i!=f&&!visited[i]){
return findcentroid(i,x,s);
}
}
return x;
}
void getcentree(int x, int f){
getsz(x,f);
int cent=findcentroid(x,f,sz[x]);
centree[x]=f;
visited[cent]=1;
for(int i:G[cent]){
if(!visited[i]) getcentree(i,cent);
}
}
感謝8e7 & IOIC講義提供模板
樹-模板
By jass921026
樹-模板
- 712