• BZOJ1316 树上的询问


    点分治常数很大所以我们跑一遍即可。

    用set记录。

    一开始没有判q[i]==0惨惨了//

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1e4+10;
     4 int sum,n,rt,q[N],p,f[N],son[N],head[N],cnt;
     5 bool v[N],ans[N];
     6 struct node{
     7     int to,nex,w;
     8 }e[N<<1];
     9 void add(int x,int y,int w)
    10 {
    11     e[++cnt].w=w;e[cnt].nex=head[x];e[cnt].to=y;head[x]=cnt;
    12 }
    13 set<int>s;
    14 void getrt(int x,int fa)
    15 {
    16     son[x]=1;f[x]=0;
    17     for(int i=head[x];i;i=e[i].nex)
    18     {
    19         int y=e[i].to;
    20         if(v[y]||y==fa)continue;
    21         getrt(y,x);
    22         son[x]+=son[y];
    23         f[x]=max(f[x],son[y]);
    24     }
    25     f[x]=max(f[x],sum-f[x]);
    26     if(f[x]<f[rt])rt=x;
    27     return;
    28 }
    29 void calc(int x,int fa,int w)
    30 {
    31     for(int i=1;i<=p;++i)
    32     {
    33         if(s.find(q[i]-w)!=s.end())ans[i]=1;
    34     }
    35     for(int i=head[x];i;i=e[i].nex)
    36     {
    37         int y=e[i].to;
    38         if(v[y]||y==fa)continue;
    39         calc(y,x,w+e[i].w);
    40     }
    41 }
    42 void update(int x,int fa,int w)
    43 {
    44     s.insert(w);
    45     for(int i=head[x];i;i=e[i].nex)
    46     {
    47         int y=e[i].to;
    48         if(v[y]||y==fa)continue;
    49         update(y,x,w+e[i].w);
    50     }
    51 }
    52 void work(int x)
    53 {
    54     v[x]=1;s.insert(0);
    55     for(int i=head[x];i;i=e[i].nex)
    56     {
    57         int y=e[i].to;
    58         if(v[y])continue;
    59         calc(y,x,e[i].w);
    60         update(y,x,e[i].w);
    61     }
    62     s.clear();
    63     for(int i=head[x];i;i=e[i].nex)
    64     {
    65         int y=e[i].to;
    66         if(v[y])continue;
    67         rt=0;sum=son[y];
    68         getrt(y,x);
    69         work(rt);    
    70     }
    71 }
    72 int main()
    73 {
    74     scanf("%d%d",&n,&p);
    75     int x,y,w;
    76     for(int i=1;i<n;++i)
    77     {
    78         scanf("%d%d%d",&x,&y,&w);
    79         add(x,y,w);add(y,x,w);
    80     }
    81     for(int i=1;i<=p;++i)
    82     {
    83         scanf("%d",&q[i]);
    84     }
    85     f[0]=sum=n;
    86     getrt(1,0);
    87     work(rt);
    88     for(int i=1;i<=p;++i)
    89     {
    90         if(ans[i]||!q[i])puts("Yes");
    91         else puts("No"); 
    92     }
    93 }
  • 相关阅读:
    第二篇:后端导出 Excel
    while 循环、for 循环
    <textarea></textarea>多行文本域
    git 基本命令
    如何让div可选中,有聚焦、失焦等事件。
    [leetcode]205. Isomorphic Strings
    [leetcode]204. Count Primes
    Here is a 10-line template that can solve most 'substring' problems子字符串问题的模板
    [leetcode]76. Minimum Window Substring
    [leetcode]166. Fraction to Recurring Decimal
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8349841.html
Copyright © 2020-2023  润新知