題意
給一棵 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...