POJ1741(点分治)

分治的时候SZ感觉是错的……但是貌似第一次找好重心就够了,之后SZ别太离谱就不会T,重心随一随缘就好……

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1e4 + 5;
int n, k, mx, SZ, ans;
struct Edge {
	int to, nxt, cost;
}e[maxn << 2];
int head[maxn], tot, size[maxn], root, dis[maxn], vis[maxn];
int l, r, Q[maxn];

void add(int u, int v, int c) {
	e[++tot].to = v, e[tot].cost = c, e[tot].nxt = head[u], head[u] = tot;
}

void GetRoot(int cur, int fa) {
	int tmp = 0;
	size[cur] = 1;
	for (int i = head[cur]; i; i = e[i].nxt) {
		int son = e[i].to;
		if (son == fa || vis[son])	continue;
		GetRoot(son, cur);
		size[cur] += size[son];
		tmp = max(tmp, size[son]);
	}
	tmp = max(tmp, SZ - size[cur]);
	if (tmp < mx)	mx = tmp, root = cur;
}

void GetDis(int cur, int fa) {
	Q[++r] = dis[cur];
	for (int i = head[cur]; i; i = e[i].nxt) {
		int son = e[i].to;
		if (son == fa || vis[son])	continue;
		dis[son] = dis[cur] + e[i].cost;
		GetDis(son, cur);
	}
}

int calc(int cur, int val) {
	l = 1, r = 0;
	dis[cur] = val;
	GetDis(cur, 0);
	sort(Q + 1, Q + 1 + r);
	int res = 0;
	while (l < r) {
		if (Q[l] + Q[r] <= k)	res += r - l, l++;
		else	r--;
	}
	return res;
}

void divide(int cur) {
	ans += calc(cur, 0);
	vis[cur] = 1;
	for (int i = head[cur]; i; i = e[i].nxt) {
		int son = e[i].to;
		if (vis[son])	continue;
		ans -= calc(son, e[i].cost);
		mx = 2e9, SZ = size[son];
		GetRoot(son, 0);
		divide(root);
	}
}

void init() {
	ans = 0, tot = 0, mx = 2e9, SZ = n;
	for (int i = 1; i <= n; i++)	head[i] = 0, vis[i] = 0;
}

int main() {
	while (scanf("%d %d", &n, &k) == 2 && (n | k)) {
		init();
		for (int u, v, cost, i = 1; i < n; i++) {
			scanf("%d %d %d", &u, &v, &cost);
			add(u, v, cost), add(v, u, cost);
		}
		GetRoot(1, 0);
		divide(root);
		printf("%d\n", ans);
	}
	return 0;
}
posted @   AlphaWA  阅读(162)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· 软件产品开发中常见的10个问题及处理方法
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· MQ 如何保证数据一致性?
· 《HelloGitHub》第 108 期
点击右上角即可分享
微信分享提示