點分治模板

2022-04-29 23:12:10 字數 1211 閱讀 2282

luogu_3806

近些日子學了點分治,當然只是學了個模板。

所謂點分治,使用於處理樹上路徑的一種分治手段。因為利用了重心的性質,時間複雜度可以保證呢。

所謂演算法流程

選取當前子樹的重心

計算路徑總數,不管路徑是否過當前重心(後面會去重)

計算起點和終點在同一顆子樹中的合法路徑(因為這條路徑不是簡單路徑),並在答案中減去

將子樹剔除出來,並在子樹中重複此過程

需要注意的點

在處理路徑(也就是深度時),一定要重新計算子節點個數(因為根有可能轉變)

時間複雜很玄學

#include #include #include #include using std::sort;

using std::max;

const int maxn=10100;

const int inf=0x7fffffff;

struct node

;node line[maxn<<1];

int head[maxn],tail;

int dep[maxn],f[maxn],size[maxn],vis[maxn],root,sum;

int d[maxn],tot;

int ans[10000011];

void add(int a,int b,int c)

void get_hry(int now,int fa)

f[now]=max(f[now],sum-size[now]);//最後和他上面的節點數取個最大值

if(f[root]>f[now]) root=now;

}void get_dep(int now,int fa)//處理路徑,這時一定要重新計算size

return ;

}void calc(int now,int dep,int delta)//核心的計算函式

void solve(int now)

return ;

}int main()

root=0;sum=n;//root,和sum分別是當前聯通塊內的根和節點數

f[root]=inf;//操作一波

get_hry(1,0);

solve(root);//點分治

for(int i=1,k;i<=m;i++)

return 0;

}

點分治模板

這兩天跟著學了一手樹上點分治模板,然後有一些感悟,決定來寫一發部落格.首先,鑑於鄙人的經驗,如果想要較快速地學習乙個新演算法,肯定還是先看一道經典的例題比較好,所以我們先來一道例題.給你一棵tree,以及這棵樹上邊的距離.問有多少對點它們兩者間的距離小於等於k 輸入格式 n n 40000 接下來n...

點分治模板

bzoj1316 由於之前板子寫得太爛了,今天把它重新整理改進了一下 vis表示每個點是否已經當過根,所以注意dfs,findroot函式的計算過程中是不會對vis進行修改的 修改時只需要考慮對dfs和solve中的有關位置進行修改即可,其它部分基本不變 include using namespac...

模板 點分治

poj 1741 include include using namespace std const int n 10010 const int inf 0x3f3f3f3f int n,k,ans int head n nxt 2 n to 2 n w 2 n tot 鏈式前向星 void add...