本人用了完全不对的点分治过了本题,错误的点在代码中标出来了:
input
10 30
5 2 2
5 9 6
2 1 6
2 4 5
9 7 9
9 10 9
4 3 3
7 6 10
7 8 6
output
41
wrong code:
#include <iostream>
#include <iomanip>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cassert>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\MPC\\Desktop\\"
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
if (y > x) return x = y,true;
return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
if (y < x) return x = y,true;
return false;
}
LL power (LL a,LL b,LL p) {
LL ans = 1;
while (b) {
if (b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
const int N = 40010;
int n,m;
vector <PII> g[N];
bool del[N];
int s[N];
int p[N],q[N];
int center;
int lp,lq;
void get_size (int u,int fa) {
if (del[u]) return ;
s[u] = 1;
for (auto [v,w] : g[u]) {
if (v == fa) continue;
get_size (v,u);
s[u] += s[v];
}
}
void get_center (int u,int fa,int tot) {
if (del[u]) return ;
int maxx = 0;
for (auto [v,w] : g[u]) {
if (v == fa) continue; //没有到下一层找重心
tomax (maxx,s[v]);
}
tomax (maxx,tot - s[u]);
if (maxx <= tot) center = u; //重心的定义错了
}
void get_dist (int u,int fa,int dist) {
if (del[u]) return ;
q[++lq] = dist;
for (auto [v,w] : g[u]) {
if (v == fa) continue;
get_dist (v,u,dist + w);
}
}
int calc (int n,int a[]) {
sort (a + 1,a + n + 1);
int ans = 0;
for (int i = n,j = 0;i >= 1;i--) {
while (j + 1 < i && a[j + 1] + a[i] <= m) j++;
tomin (j,i - 1);
ans += j;
}
return ans;
}
int solve (int u) {
get_size (u,-1);
center = -1;
get_center (u,-1,s[u]);
u = center;
del[u] = true;
int ans = 0;
lp = 0;
for (auto [v,w] : g[u]) {
lq = 0;
get_dist (v,-1,w);
ans -= calc (lq,q);
for (int i = 1;i <= lq;i++) {
if (q[i] <= m) ans++;
p[++lp] = q[i];
}
}
ans += calc (lp,p);
for (auto [v,w] : g[u]) ans += solve (v);
return ans;
}
int main () {
cin >> n;
for (int i = 1;i <= n - 1;i++) {
int a,b,w;
cin >> a >> b >> w;
g[a].pb ({b,w}),g[b].pb ({a,w});
}
cin >> m;
cout << solve (1) << endl;
return 0;
}