AcWing 264 權值 (點分治)

2021-10-11 04:38:11 字數 1463 閱讀 6486

題意

給一棵 n

nn 個節點的樹,邊帶權。求一條簡單路徑,使得這條路徑上邊的權值之和為 k

kk ,且包含邊的數量最少。

解法樹上路徑詢問?立即推:點分治!

**

#pragma region

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

#define rep(i, a, n) for (int i = a; i <= n; ++i)

#define per(i, a, n) for (int i = n; i >= a; --i)

#pragma endregion

const

int maxn =

2e5+5;

const

int inf =

0x3f3f3f3f

;int n, k;

vectorint,

int>> g[maxn]

;int sz[maxn]

, rt, dep[maxn]

, minn[

int(

1e6+5)

];ll d[maxn]

;bool vis[maxn]

;void

dfs_rt

(int u,

int f,

int tot)

maxx =

max(maxx, tot - sz[u]);

if(maxx *

2<= tot) rt = u;

}int cnt;

void

dfs_ans

(int u,

int f,

int&ans)

}void

dfs_minn

(int u,

int f,

int val)

}int

work

(int u,

int f,

int tot)

dfs_minn

(u, f,-1

);for(

auto e : g[u]

)return ans;

}int

main()

);g[v]

.push_back()

;}int ans =

work(1

,0, n)

;printf

("%d\n"

, ans == inf ?-1

: ans)

;}

AcWing252 樹(點分治)

本題如果k的範圍較小的話,可以使用樹狀陣列記錄答案,但是因為很大 考慮使用雙指標 容斥原理。也就是直接算整個子樹的答案,之後再在列舉兒子節點的時候,把加上u v這條邊的合法答案全部清除,這樣就做到了不重不漏 includeusing namespace std typedef long long l...

AcWing 252 樹 點分治

每次找到樹的重心,分治下去統計答案 經過當前根節點的路徑 即可 統計答案使用了指標掃瞄陣列的方法,要注意去掉同一子樹內路徑的答案 還可以直接在樹上統計子樹答案 這個方法的好處是保證了分開的兩段路徑不在同一子樹內 但是要使用平衡樹,複雜度高 include include include includ...

AcWing252 樹 (點分治模板題)

傳送門 做一道點分治的裸題 這個題要求一顆樹上路徑長度小於等於 k 的路徑的數量。可以用樹狀陣列維護子樹到重心距離在 0,k dis 的節點數量。但樹狀陣列沒法維護 0 的資訊,就同意偏移 1 include define lowbit x x x using namespace std const...