zoukankan      html  css  js  c++  java
  • bzoj4042

    比较好的树形dp,涉及到树上路径的题目,我们往往考虑对路径分类

    当我们考虑以x为根的子树,有这样几类路径

    1. 起点终点都在子树内

    2. 一个点延伸到子树外

    对于要选择另一个点在子树外的路径,要建立在不破坏儿子子树内的路径基础上

    因为破坏会破坏多条,而只能多选择一条,不合适

    因此我们考虑树dp,设f[x]为路径起点终点在子树内能选择的最多路径数目,d[x]表示还没用过的另一个点在x子树外的路径的集合

    我们知道,对于x的每个孩子d,d[y]中最多只会有1条路径被选中,因此我们可以用状压dp解决

      1 type node=record
      2        po,next:longint;
      3      end;
      4 
      5 var a:array[0..1200,0..1200] of longint;
      6     w:array[0..1010,0..1010] of boolean;
      7     e:array[0..2400] of node;
      8     g,f,q,b,s,p:array[0..1200] of longint;
      9     len,i,tt,n,m,x,y:longint;
     10 
     11 function max(a,b:longint):longint;
     12   begin
     13     if a>b then exit(a) else exit(b);
     14   end;
     15 
     16 procedure add(x,y:longint);
     17   begin
     18     inc(len);
     19     e[len].po:=y;
     20     e[len].next:=p[x];
     21     p[x]:=len;
     22   end;
     23 
     24 function check(x,y:longint):boolean;
     25   var i,j:longint;
     26   begin
     27     for i:=1 to s[x] do
     28       for j:=1 to s[y] do
     29         if w[a[x,i],a[y,j]] then exit(true);
     30     exit(false);
     31   end;
     32 
     33 procedure dfs(x,fa:longint);
     34   var st,mx,i,y,t,j,k:longint;
     35   begin
     36     f[x]:=0;
     37     s[x]:=1;
     38     a[x,s[x]]:=x;
     39     i:=p[x];
     40     while i<>0 do
     41     begin
     42       y:=e[i].po;
     43       if y<>fa then
     44         dfs(y,x);
     45       i:=e[i].next;
     46     end;
     47     i:=p[x];
     48     t:=0;
     49     while i<>0 do
     50     begin
     51       y:=e[i].po;
     52       if y<>fa then
     53       begin
     54         f[x]:=f[x]+f[y];
     55         if check(x,y) then inc(f[x])
     56         else begin
     57           inc(t);
     58           q[t]:=y;
     59         end;
     60       end;
     61       i:=e[i].next;
     62     end;
     63     k:=0;
     64     for i:=1 to t-1 do
     65       for j:=i+1 to t do
     66         if check(q[i],q[j]) then
     67         begin
     68           inc(k);
     69           b[k]:=(1 shl (i-1)) or (1 shl (j-1));
     70         end;
     71     st:=0;
     72     mx:=0;
     73     for i:=0 to 1 shl t-1 do
     74     begin
     75       g[i]:=0;
     76       for j:=1 to k do
     77         if b[j] and i=b[j] then
     78           g[i]:=max(g[i],g[i xor b[j]]+1);
     79       if g[i]>mx then
     80       begin
     81         mx:=g[i];
     82         st:=0;
     83       end;
     84       if g[i]=mx then st:=st or ((1 shl t-1) xor i);
     85     end;
     86     f[x]:=f[x]+mx;
     87     for i:=1 to t do
     88       if (1 shl (i-1)) and st>0 then
     89       begin
     90         y:=q[i];
     91         for j:=1 to s[y] do
     92         begin
     93           inc(s[x]);
     94           a[x,s[x]]:=a[y,j];
     95         end;
     96       end;
     97   end;
     98 
     99 begin
    100   readln(tt);
    101   while tt>0 do
    102   begin
    103     dec(tt);
    104     len:=0;
    105     fillchar(p,sizeof(p),0);
    106     readln(n);
    107     for i:=1 to n-1 do
    108     begin
    109       readln(x,y);
    110       add(x,y);
    111       add(y,x);
    112     end;
    113     readln(m);
    114     fillchar(w,sizeof(w),false);
    115     for i:=1 to m do
    116     begin
    117       readln(x,y);
    118       w[x,y]:=true;
    119       w[y,x]:=true;
    120     end;
    121     dfs(1,0);
    122     writeln(f[1]);
    123   end;
    124 end.
    View Code
  • 相关阅读:
    cancel-ng-swipe-right-on-child
    css.day.05.eg
    css.day05
    css.day04.eg
    css.day04
    css.day03.eg
    css.day03
    css.day02.eg
    九月十月百度人搜,阿里巴巴,腾讯华为笔试面试八十题(第331-410题)(转)
    阿里巴巴笔试题选解
  • 原文地址:https://www.cnblogs.com/phile/p/4590630.html
Copyright © 2011-2022 走看看