点分治TLE on #7#9求调
查看原帖
点分治TLE on #7#9求调
965685
yyrwlj楼主2024/6/10 18:51

oi-wiki的写法

#include <iostream>
#include <vector>
using namespace std;
const int N = 10005, K = 10000005, inf = 1e9;
struct Edge{
	int e, to, nxt;
}g[N << 1];
int h[N], idx;
bool ans[N], st[N];
int vis[K], Time;
int siz[N], mx[N], dist[N], sum, root;
int dis[N], tot;
int q[N], n, m;
void add(int a,int b,int c)
{
	g[++idx] = {c, b, h[a]}, h[a] = idx;
}
void dfs_size(int u,int fa)
{
	siz[u] = 1;
	mx[u] = 0;
	for (int i = h[u]; i; i = g[i].nxt)
	{
		int j = g[i].to;
		if (j == fa || st[j])
			continue;
		dfs_size(j, u);
		mx[u] = max(mx[u], siz[j]);
		siz[u] += siz[j];
	}
	mx[u] = max(mx[u], sum - siz[u]);
	if (mx[u] < mx[root])
		root = u;
}
void dfs_dist(int u,int fa)
{
	dis[++ tot] = dist[u];
	for (int i = h[u]; i; i = g[i].nxt)
	{
		int j = g[i].to;
		if (j == fa || st[j])
			continue;
		dist[j] = dist[u] + g[i].e;
		if (dist[j] <= 10000000)
			dfs_dist(j, u);
	}
}
void dfs(int u,int fa)
{
	vis[0] = ++ Time;
	st[u] = true;
	for (int i = h[u]; i; i = g[i].nxt)
	{
		int j = g[i].to;
		if (j == fa || st[j])
			continue;
		tot = 0;
		dist[j] = g[i].e;
		dfs_dist(j, u);
		for (int d=1;d<=tot;d++)
			for (int k=1;k<=m;k++)
				if (dis[d] <= q[k])
					ans[k] |= vis[q[k] - dis[d]] == Time;
		for (int d=1;d<=tot;d++)
			vis[dis[d]] = Time;
	}
	for (int i = h[u]; i; i = g[i].nxt)
	{
		int j = g[i].to;
		if (j == fa || st[j])
			continue;
		sum = siz[j];
		root = 0;
		mx[root] = inf;
		dfs_size(j, u);
		dfs_size(root, root);
		dfs(j, u);
	}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1;i<n;i++)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add(a, b, c);
		add(b, a, c);
	}
	for (int i=1;i<=m;i++)
		scanf("%d", &q[i]);
	mx[root] = inf;
	sum = n;
	dfs_size(1, 1);
	dfs_size(root, root);
	dfs(root, root);
	for (int i=1;i<=m;i++)
		if (ans[i])
			puts("AYE");
		else
			puts("NAY");
	return 0;
}
2024/6/10 18:51
加载中...