zoukankan      html  css  js  c++  java
  • 【树形dp 思维题】HHHOJ#483. NOIP司马懿

    要注意利用一些题目的特殊条件吧。

    题目大意

    有一颗$n$个点带点权$a_i$的树,$q$次询问树上是否存在长度为$l$的路径。

    $n,q,lle 10^5,0 le a_i le 2$


    题目分析

    做的时候没有用好$a_ile 2$的条件,以为是道玄学的点分。

    将权值按奇偶性分类,那么因为每个点只能是$0,1,2$,所以对树上的每一条路径,每加入一个$1$点,其子路径所能表示的路径都+1,奇偶性就改变了;每加入一个$2$点,其子路径所能表示的路径都+2,奇偶性不变。

    这样看来,按奇偶性分成的两类路径各自都是连续的。

    那么变为一个子问题:求树上最长的路径。$f_{i,0/1}$表示点$i$包括自身向下的链中、奇偶性为$0/1$的最长链长,这个问题用dp就很容易解决了。

     1 #include<bits/stdc++.h>
     2 const int maxn = 100035;
     3 const int maxm = 200035;
     4 
     5 int n,m,w[maxn],f[maxn][2],ans[2];
     6 int edgeTot,head[maxn],nxt[maxm],edges[maxm];
     7 
     8 int read()
     9 {
    10     char ch = getchar();
    11     int num = 0, fl = 1;
    12     for (; !isdigit(ch); ch=getchar())
    13         if (ch=='-') fl = -1;
    14     for (; isdigit(ch); ch=getchar())
    15         num = (num<<1)+(num<<3)+ch-48;
    16     return num*fl;
    17 }
    18 void addedge(int u, int v)
    19 {
    20     edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
    21     edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
    22 }
    23 void Max(int &x, int y){x = x>y?x:y;}
    24 void dfs(int x, int fa)
    25 {
    26     f[x][w[x]&1] = w[x];
    27     for (int i=head[x]; i!=-1; i=nxt[i])
    28     {
    29         int v = edges[i];
    30         if (v==fa) continue;
    31         dfs(v, x);
    32         Max(ans[0], f[x][0]+f[v][0]);
    33         Max(ans[0], f[x][1]+f[v][1]);
    34         Max(ans[1], f[x][1]+f[v][0]);
    35         Max(ans[1], f[x][0]+f[v][1]);
    36         Max(f[x][w[x]&1], f[v][0]+w[x]);
    37         Max(f[x][1-(w[x]&1)], f[v][1]+w[x]);
    38     }
    39     Max(ans[0], f[x][0]), Max(ans[1], f[x][1]);
    40 }
    41 int main()
    42 {
    43     memset(head, -1, sizeof head);
    44     n = read(), m = read();
    45     for (int i=1; i<=n; i++) w[i] = read();
    46     for (int i=1; i<n; i++) addedge(read(), read());
    47     dfs(1, 0);
    48     for (int x; m; --m)
    49     {
    50         x = read();
    51         puts(ans[x&1]>=x?"YES":"NO");
    52     }
    53     return 0;
    54 }

    END

  • 相关阅读:
    随手
    会使用基本的Render函数后,就会想,这怎么用 v-for/v-if/v-model;我写个vue Render函数进阶
    iframe子页面与父页面元素的访问以及js变量的访问[zhuan]
    vue element-ui 的奇怪组件el-switch
    URLSearchParams和axios的post请求(防忘记)
    ios vue2.0使用html5中的audio标签不能播放音乐
    Unity Input System教程
    关于OpenGPU.org
    Better ultra_simple for Slamtec RPLIDAR on Linux
    八字心得
  • 原文地址:https://www.cnblogs.com/antiquality/p/11183887.html
Copyright © 2011-2022 走看看