【poj2114】点分治(离线)
boatherds 2s 64M by czy
求一颗树上距离为K的点对是否存在
输入数据
n,m
接下来n-1条边a,b,c描述a到b有一条长度为c的路径
接下来m行每行询问一个K
输出数据
对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NYE”(不包含引号)
数据范围
对于30%的数据n<=100
对于60%的数据n<=1000,m<=50
对于100%的数据n<=10000,m<=100,c<=1000,K<=10000000
点分治。
但是每次询问会超时,所以需要离线。
就把K都存起来,每次询问的时候都for一遍K。
代码:
1 // #pragma comment(linker,"/STACK:102400000,102400000")
2 #include<cstdio>
3 #include<cstdlib>
4 #include<cstring>
5 #include<iostream>
6 #include<algorithm>
7 using namespace std;
8
9 const int N=10010;
10 int n,m,sl,kl,tl,vl,len,first[N],mark[N],s[N],t[N],d[N],size[N],K[N],ans[N];//,v[N];
11 bool v[10000010];
12 struct node{
13 int x,y,d,next;
14 }a[2*N];
15
16 bool cmp(int x,int y){return x<y;}
17
18 void ins(int x,int y,int d)
19 {
20 a[++len].x=x;a[len].y=y;a[len].d=d;
21 a[len].next=first[x];first[x]=len;
22 }
23
24 void find_root(int x,int fa,int tot,int &root)
25 {
26 size[x]=1;
27 bool bk=1;
28 for(int i=first[x];i;i=a[i].next)
29 {
30 int y=a[i].y;
31 if(y==fa || mark[y]) continue;
32 find_root(y,x,tot,root);
33 size[x]+=size[y];
34 if(2*size[y]>tot) bk=0;
35 }
36 if(bk && 2*(tot-size[x])<=tot) root=x;
37 }
38
39 void DFS(int x,int fa)
40 {
41 for(int i=1;i<=kl;i++)
42 {
43 if(K[i]>=d[x] && v[K[i]-d[x]]) ans[i]=1;
44 }
45 // if(ans==1) return ;
46 t[++tl]=d[x];
47 size[x]=1;
48 for(int i=first[x];i;i=a[i].next)
49 {
50 int y=a[i].y;
51 if(y==fa || mark[y]) continue;
52 d[y]=d[x]+a[i].d;
53 DFS(y,x);
54 size[x]+=size[y];
55 }
56 }
57
58 void dfs(int x,int tot)
59 {
60 find_root(x,0,tot,x);
61 v[0]=1;sl=0;//ssl=0;
62 // s[++sl]=x;
63 mark[x]=1;
64 for(int i=first[x];i;i=a[i].next)
65 {
66 int y=a[i].y;
67 if(mark[y]) continue;
68 tl=0;d[y]=a[i].d;
69 DFS(y,x);
70 // if(ans==1) break;
71 for(int j=1;j<=tl;j++) v[t[j]]=1,s[++sl]=t[j];
72 }
73 for(int i=1;i<=sl;i++) v[s[i]]=0;
74 // if(ans==1) return ;
75 for(int i=first[x];i;i=a[i].next)
76 {
77 int y=a[i].y;
78 if(mark[y]) continue;
79 dfs(y,size[y]);
80 }
81 }
82
83 int main()
84 {
85 // freopen("a.in","r",stdin);
86 freopen("boatherds.in","r",stdin);
87 freopen("boatherds.out","w",stdout);
88 scanf("%d%d",&n,&kl);
89 len=0;
90 memset(v,0,sizeof(v));
91 memset(first,0,sizeof(first));
92 for(int i=1;i<n;i++)
93 {
94 int x,y,c;
95 scanf("%d%d%d",&x,&y,&c);
96 ins(x,y,c);
97 ins(y,x,c);
98 }
99 for(int i=1;i<=kl;i++) scanf("%d",&K[i]);
100 memset(ans,0,sizeof(ans));
101 dfs(1,n);
102 for(int i=1;i<=kl;i++)
103 {
104 if(ans[i]) printf("AYE\n");
105 else printf("NAY\n");
106 }
107 return 0;
108 }