习题:点分治(淀粉质)

题目

传送门

思路

如题目所示,就是一道淀粉质的版题

代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
using namespace std;
#define MAXN 100000
#define MAXM 200000
int n,m;
int cnt;
int focus;
int s;
int head[MAXN+5];
int val[MAXN+5];
int nxt[MAXM+5];
int to[MAXM+5];
int siz[MAXN+5];
int maxx[MAXN+5];
int dis[MAXN+5];
int ans[10000005];
int v[MAXN];
int lenv;
bool vis[MAXN+5];
void add_edge(int u,int v,int w)
{
	to[++cnt]=v;
	val[cnt]=w;
	nxt[cnt]=head[u];
	head[u]=cnt;
}
void find_focus(int u,int fa)
{
	siz[u]=1;
	maxx[u]=0;
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(!vis[v]&&v!=fa)
		{
			find_focus(v,u);
			siz[u]+=siz[v];
			maxx[u]=max(maxx[u],siz[v]);
		}
	}
	maxx[u]=max(maxx[u],s-siz[u]);
	if(maxx[u]<maxx[focus])
		focus=u;
}
void solve_dis(int u,int fa)
{
	v[lenv++]=dis[u];
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(!vis[v]&&v!=fa)
		{
			dis[v]=dis[u]+val[i];
			solve_dis(v,u);
		}
	}
}
void solve(int s,int l,int w)
{
	lenv=0;
	dis[s]=l;
	solve_dis(s,0);
	for(int i=0;i<lenv;i++)
		for(int j=i+1;j<lenv;j++)
			if(v[i]+v[j]<=10000000)
				ans[v[i]+v[j]]+=w;

}
void dfs(int u)
{
	solve(u,0,1);
	vis[u]=1;
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(!vis[v])
		{
			solve(v,val[i],-1);
			focus=0;
			//maxx[0]=n+1;
			s=siz[u];
			find_focus(v,u);
			dfs(focus);
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1,u,v,w;i<n;i++)
	{
		cin>>u>>v>>w;
		add_edge(u,v,w);
		add_edge(v,u,w);
	}
	s=n;
	maxx[0]=n+1;
	find_focus(1,0);
	dfs(focus);
	for(int i=1,k;i<=m;i++)
	{
		cin>>k;
		if(ans[k])
			cout<<"AYE\n";
		else
			cout<<"NAY\n";
	}
	return 0;
}
posted @ 2019-12-13 21:06  loney_s  阅读(166)  评论(0)    收藏  举报