寻找树上存在长度为k点对,树上的分治 代码和 这个 差不多 ,改一下判断的就好
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <algorithm> #include <cstdio> #include <vector> #include <string.h> using namespace std; const int maxn=10004; int H[maxn],nx[maxn*2],to[maxn*2],numofE,dist[maxn*2]; void add(int u,int v, int d) { numofE++; dist[numofE]=d; to[numofE]=v; nx[numofE]=H[u]; H[u]=numofE; } void init(int N){ numofE=0; memset(H,0,sizeof(H)); } int ans; int subnum[maxn],Q[maxn+10],fa[maxn]; bool center[maxn]; int N,K; int searchroot(int cur) { int rear=0,root=cur; Q[rear++]=cur;fa[cur]=0; for(int i=0; i<rear; i++) { int x=Q[i]; for(int j=H[x]; j; j=nx[j]) if(to[j]!=fa[x]&¢er[to[j]]==false) Q[rear++]=to[j],fa[to[j]]=x; } int MIN=maxn; for(int i=rear-1; i>=0; i--) { int x=Q[i]; subnum[x]=1; int MA=0; for(int j=H[x]; j ; j=nx[j]) if(to[j]!=fa[x]&¢er[to[j]]==false) MA=max(MA,subnum[to[j]]),subnum[ x ]+=subnum[ to[j] ]; MA=max(MA,rear-subnum[x]); if(MIN>MA)MIN=MA,root=x; } return root; } int P[maxn]; int count_pair(int s, int t) { int ge=0,l=t,r=t; for(int i=s; i<t; i++) { while(r>s&&P[i]+P[r-1]>K)r--; while(l>s&&P[i]+P[l-1]>=K)l--; if(i>=l&&i<r)ge+=r-l-1; else ge+=r-l; } return ge/2; } void updateedg(int s, int cur, int d) { int rear=0; Q[rear++]=cur;fa[cur]=0;P[s]=d; for(int i=0; i<rear; i++) { int x=Q[i]; for(int j=H[x];j; j=nx[j]) { int tto=to[j]; if(center[tto]||tto==fa[x])continue; P[s+rear]=P[s+i]+dist[j],Q[rear++]=tto,fa[tto]=x; } } sort(P+s,P+s+rear); } int dfs(int s, int cur, int d) { int root,tot=1; root=searchroot(cur); center[root]=true; for(int i=H[root]; i ;i=nx[i]) { int tto=to[i]; if(center[tto])continue; int n=dfs(s+tot,tto,dist[i]); if(ans>0){ center[root]=false;return 0; } ans-=count_pair(s+tot,s+tot+n); tot+=n; } P[s]=0; sort(P+s,P+s+tot); ans+=count_pair(s,s+tot); if(ans>0){ center[root]=false;return 0; } center[root]=false; updateedg(s,cur,d); return tot; } int main() { for(;;) { scanf("%d",&N); if(N==0)break; init(N); for(int i=1;i<=N; i++) { int d; for(;;) { scanf("%d",&d); if(d==0)break; int c; scanf("%d",&c); add(i,d,c);add(d,i,c); } } for(;;) { scanf("%d",&K);if(K==0)break; ans=0; dfs(0,1,0); if(ans>0) puts("AYE"); else puts("NAY"); } puts("."); } return 0; } /* 6 2 1 3 1 4 1 0 0 5 1 6 1 0 0 0 0 2 */