• bzoj1040


    论环形dp的重要!

    其实这个环比较简单,稍微分析一下就知道,

    这是一个简单环,并且每个联通块里只含有一个。

    我觉得把处理环的关键,就是要找出环形和线形(树形)有什么区别。

    如果我们从某处断开的做dp的话,转移的结果只对根节点有影响(不确定);

    然后我猜测应该只要找到环上相邻两点然后断开分别以他们为根做treedp就可以了

    结果真的是这样……

    总感觉缺点什么……

    有待进一步思考……

     1 type node=record
     2        point,next:longint;
     3      end;
     4 
     5 var edge:array[0..2000010] of node;
     6     can:array[0..2000010] of boolean;
     7     v:array[0..1000010] of boolean;
     8     p,w:array[0..1000010] of longint;
     9     f:array[0..1000010,0..1] of int64;
    10     len,find,n,u,z,i:longint;
    11     ans,res:int64;
    12 
    13 function max(a,b:int64):int64;
    14   begin
    15     if a>b then exit(a) else exit(b);
    16   end;
    17 
    18 procedure add(x,y:longint);
    19   begin
    20     inc(len);
    21     edge[len].point:=y;
    22     edge[len].next:=p[x];
    23     can[len]:=true;
    24     p[x]:=len;
    25   end;
    26 
    27 procedure dfs(x:longint);   //找环
    28   var i,y:longint;
    29   begin
    30     v[x]:=true;
    31     i:=p[x];
    32     while i<>-1 do
    33     begin
    34       y:=edge[i].point;
    35       if can[i] and not v[y] then   
    36       begin
    37         can[i xor 1]:=false;   //注意防止因为同一条边而回头
    38         dfs(y);
    39         can[i xor 1]:=true;    //解除标记
    40       end
    41       else if can[i] and v[y] then
    42       begin
    43         u:=x;
    44         z:=y;
    45         find:=i;
    46       end;
    47       i:=edge[i].next;
    48     end;
    49   end;
    50 
    51 procedure treedp(x:longint);
    52   var i,y:longint;
    53   begin
    54     i:=p[x];
    55     f[x,0]:=0;
    56     f[x,1]:=w[x];
    57     while i<>-1 do
    58     begin
    59       y:=edge[i].point;
    60       if can[i] then   
    61       begin
    62         can[i xor 1]:=false;
    63         treedp(y);
    64         can[i xor 1]:=true;
    65         f[x,0]:=f[x,0]+max(f[y,0],f[y,1]);  //基本的treedp
    66         f[x,1]:=f[x,1]+f[y,0];
    67       end;
    68       i:=edge[i].next;
    69     end;
    70   end;
    71 
    72 procedure dp(i:longint);
    73   begin
    74     dfs(i);
    75     can[find]:=false;    //断开
    76     can[find xor 1]:=false;
    77     treedp(u);
    78     res:=f[u,0];
    79     treedp(z);
    80     ans:=ans+max(f[z,0],res);  //都是不取根,这里是凭感觉写的,欢迎指教
    81   end;
    82 
    83 begin
    84   len:=-1;
    85   readln(n);
    86   fillchar(p,sizeof(p),255);
    87   for i:=1 to n do
    88   begin
    89     readln(w[i],z);
    90     add(z,i);
    91     add(i,z);
    92   end;
    93   for i:=1 to n do
    94     if not v[i] then dp(i);
    95   writeln(ans);
    96 end.
    View Code
  • 相关阅读:
    STL源代码剖析(二)
    局域网部署docker--从无到有创建自己的docker私有仓库
    Leetcode Add two numbers
    GDIPlus绘制桌面歌词
    Android中apk动态载入技术研究(2)android插件化及实现
    jq 地区(省市县区)联动菜单
    System.Diagnostics.Process.Start的妙用
    aaaa
    RESTful Web 服务:教程
    芒果TV 视频真实的地址获取
  • 原文地址:https://www.cnblogs.com/phile/p/4473221.html
Copyright © 2020-2023  润新知