Solution - P4178 Tree

咕。好像要吃 flag 了。

思路

淀粉质模板题(的变形),不难。

淀粉质都会吧。点分治出来以后用双指针干出路径个数就行了。注意同子树的情况。

代码

#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 40004
using namespace std;

int to[N<<1], val[N<<1], nxt[N<<1], head[N], gsiz = 1;
#define mkarc(u,v,w) (++gsiz, to[gsiz]=v, val[gsiz]=w, nxt[gsiz]=head[u], head[u]=gsiz)
int siz[N], vis[N], dis[N], tmp[N], cnt, cntt;
int n, k;
int ans;

inline void dfs1(rint u, rint fa){
	siz[u] = 1;
	for(rint i = head[u]; i; i = nxt[i]){
		rint v = to[i];
		if(v == fa || vis[v]) continue;
		dfs1(v, u);
		siz[u] += siz[v];
	}
	return;
} 

inline void dfs2(rint u, rint fa, rint root, rint& minn, rint& k){
	rint mink = siz[root]-siz[u];
	for(rint i = head[u]; i; i = nxt[i]){
		rint v = to[i];
		if(v == fa || vis[v]) continue;
		mink = max(mink, siz[v]);
		dfs2(v, u, root, minn, k);
	}
	if(mink < minn) k = u;
	return;
}

inline void dfs3(rint u, rint fa, rint dep){
	tmp[++cntt] = dep;
	for(rint i = head[u]; i; i = nxt[i]){
		rint v = to[i];
		if(v == fa || vis[v]) continue;
		dfs3(v, u, dep+val[i]);
	}
	return;
}

inline void solve(rint u){
//puts("QFR");
	cnt = 0;
	rint minn = 1e9+7, g;
	dfs1(u, 0);
	dfs2(u, 0, u, minn, g);
	vis[g] = true;
	rint delta = 0, res = 0;
	dis[++cnt] = 0;
	for(rint e = head[g]; e; e = nxt[e]){
		cntt = 0;
		rint v = to[e];
		if(vis[v]) continue;
		dfs3(v, u, val[e]);
		sort(tmp+1, tmp+cntt+1);
		rint l = 1, r = cntt;
		while(l <= r){
			while(l <= r && tmp[l]+tmp[r] > k) --r;
			if(l <= r) delta += (r-l+1), ++l;
		}
		for(rint i = 1; i <= cntt; ++i)
			dis[++cnt] = tmp[i];
	}
	sort(dis+1, dis+cnt+1);
	rint l = 1, r = cnt;
	while(l <= r){
		while(l <= r && dis[l]+dis[r] > k) --r;
		if(l <= r) res += (r-l+1), ++l;
	}
	ans += res-delta-1;
	for(rint i = head[g]; i; i = nxt[i])
		if(!vis[to[i]]) solve(to[i]);
	return;
}

int main(){
	scanf("%d", &n);
	for(rint i = 1; i < n; ++i){
		rint u, v, w;
		scanf("%d %d %d", &u, &v, &w);
		mkarc(u, v, w), mkarc(v, u, w);
	}
	scanf("%d", &k);
	solve(1);
	printf("%d", ans);
	return 0;
}

posted @ 2025-05-16 23:11  Hootime  阅读(2)  评论(0)    收藏  举报