luoguP3806 【模板】点分治1

本文深入探讨了一种基于图论的复杂算法,详细介绍了其数据结构、核心算法流程及实际应用案例。通过递归和深度优先搜索,算法能够高效地解决特定问题,如寻找最短路径和最小生成树等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 10004  
#define inf 10000003
using namespace std;
int edges,n,Q,sn,root,tl; 
bool is[inf]; 
int hd[maxn],to[maxn<<1],nex[maxn<<1],val[maxn<<1];  
int answer[maxn], que[200], vis[maxn], f[maxn], siz[maxn], dep[maxn], mine[inf], dis1[maxn];        
inline void add(int u,int v,int c)
{
	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; 
} 
void Getroot(int u,int fa)
{
	f[u]=0, siz[u]=1; 
	for(int i=hd[u];i;i=nex[i])
	{
		int v=to[i]; 
		if(vis[v]||v==fa) continue; 
		Getroot(v,u), siz[u]+=siz[v]; 
		f[u]=max(f[u], siz[v]); 
	}
	f[u]=max(f[u], sn-siz[u]); 
	if(f[u]<f[root]) root=u;     
}
inline void getdis(int u,int fa,int d)
{      
	dis1[++tl] = d;  
	for(int i=hd[u];i;i=nex[i])
	{ 
		int v=to[i]; 
		if(v==fa||vis[v]) continue; 
		getdis(v, u, d + val[i]);   
	}
}
inline void calc(int u)
{
	tl=0; 
	mine[0]=1;        
	for(int i=hd[u];i;i=nex[i])
	{
		int v=to[i];
		if(vis[v]) continue; 
		int pdl=tl; 
		getdis(v, u, val[i]); 
		for(int j=pdl+1;j<=tl;++j) 
			for(int o=1;o<=Q;++o)
			{
				if(que[o]>=inf||que[o] < dis1[j]) continue;  
				is[que[o]]|=mine[que[o]-dis1[j]];     
			}   
		for(int j=pdl+1;j<=tl;++j) mine[dis1[j]]=1; 
	} 
    for(int i=1;i<=tl;++i) mine[dis1[i]]=0;      
}
void solve(int u)
{
	int i,v;
	vis[u]=1;    
	calc(u);     
	for(i=hd[u];i;i=nex[i])
	{
		v=to[i]; 
		if(vis[v]) continue;   
		root=0,sn=siz[v],Getroot(v, u); 
		solve(root);      
	}
}
int main()
{
	int i,j; 
	// setIO("input"); 
	scanf("%d%d",&n,&Q);
	for(i=1;i<n;++i)
	{
		int u,v,c; 
		scanf("%d%d%d",&u,&v,&c); 
		add(u,v,c), add(v,u,c);   
	}
	for(i=1;i<=Q;++i) scanf("%d",&que[i]);  
	sn=n,f[0]=maxn,Getroot(1,0),solve(root);  
	for(i=1;i<=Q;++i) if(is[que[i]]) puts("AYE"); else puts("NAY");   
	return 0; 
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值