zoukankan      html  css  js  c++  java
  • 1040: [ZJOI2008]骑士

        首先是因为想学仙人掌图才来先拿这题热热身,结果&……竟然调了一个晚上我的傻叉!(其中一大半的时候是在郁闷hzwer和Greens的代码画风不一样,后来才发现一个用拓扑一个用树dp23333,以后代码坚决自己解决

    贴一下hzwer大神的题解吧:http://hzwer.com/1729.html

    以及云的代码:http://hi.baidu.com/greencloud/archive/tag/dp?page=4

    treedp:
    首先我们发现一个骑士只会觉得另一个骑士丑(233),然后我们想到了树,因为树上每个点只有一个入度,所以边建为从被讨厌的人指向讨厌他的。但是会出现环的情况……这时候一定是在树根那里有个环!(画图就可以发现一定是这样,如果不是在树根那么就会有出现入度为2的情况,显然不可能……)。然后就先处理出不再环上的每个点与各自的子树的情况(dp[x,0]表示x取,dp[x,1],表示x不取),由于树上只有一个环,so那些环上的点的儿子们如果不再环上那子树一定是棵树不会出现环,so是可以用treedp递归处理出来。(然后拓扑的方法就相反啦,边是从某个人指向这个人讨厌的人,那么那些入度为0的点就是老好人,然后从这些老好人开始推,找老好人讨厌的人&……算过去)

    然后就是处理环上怎么取最大的问题啦。

    破环成链,这时候就先不考虑链头与链尾不能同时取的情况,跑一边dp,然后再来考虑链头和链尾的限制,也就是链头取的时候链尾不能取,链头不取的时候链尾可取可不取……

    (我X我最近什么鬼状态!!!连傻叉题都不会写了)

    type
      arr=record
        toward,next:longint;
      end;
    
    const
      maxn=1002333;
    
    var
      edge:array[0..maxn]of arr;
      first,fa,link,from:array[0..maxn]of longint;
      value:array[0..maxn]of int64;
      chose:array[0..maxn]of boolean;
      dp:array[0..maxn,0..1]of int64;
      f:array[0..maxn,1..4]of int64;
      n,m,tot:longint;
    
    function max(x,y:int64):int64;
    begin
      if x<y then exit(y);
      exit(x);
    end;
    
    procedure addedge(j,k:longint);
    begin
      inc(tot);
      edge[tot].toward:=k;
      edge[tot].next:=first[j];
      first[j]:=tot;
    end;
    
    procedure treedp(x:longint);
    var
      i,too:longint;
    begin
      dp[x,1]:=value[x];
      dp[x,0]:=0;
      chose[x]:=false;
      i:=first[x];
      while i>0 do begin
        too:=edge[i].toward;
        treedp(too);
        dp[x,0]:=dp[x,0]+max(dp[too,0],dp[too,1]);
        dp[x,1]:=dp[x,1]+dp[too,0];
        i:=edge[i].next;
      end;
    end;
    
    procedure into;
    var
      i,j:longint;
    begin
      readln(n);
      for i:=1 to n do begin
        chose[i]:=true;
        read(value[i],j);
        addedge(j,i);
        fa[i]:=j;
      end;
    end;
    
    procedure work;
    var
      i,j,x,now,sum,too:longint;
      ans,answer:int64;
    begin
      answer:=0;
      for i:=1 to n do
        if chose[i] then begin
          sum:=0;
          x:=i;
          while chose[x] do begin
            chose[x]:=false;
            x:=fa[x];
            //from[fa[x]]:=x;
            from[fa[x]]:=x;
          end;
          now:=x;
          repeat
            j:=first[x];
            dp[x,1]:=value[x];
            while j>0 do  begin
              too:=edge[j].toward;
              if too<>from[x] then begin
                treedp(too);
                dp[x,0]:=dp[x,0]+max(dp[too,0],dp[too,1]);
                dp[x,1]:=dp[x,1]+dp[too,0];
              end;
              j:=edge[j].next;
            end;
            inc(sum);
            link[sum]:=x;
            x:=fa[x];
          until x=now;
          ans:=0;
          f[1,1]:=dp[link[1],0];
          f[1,2]:=dp[link[1],1];
          f[1,3]:=dp[link[1],0];
          f[1,4]:=dp[link[1],0];
          for j:=2 to sum do begin
            x:=link[j];
            f[j,1]:=max(f[j-1,1],f[j-1,2])+dp[x,0];
            f[j,2]:=f[j-1,1]+dp[x,1];
            f[j,3]:=max(f[j-1,3],f[j-1,4])+dp[x,0];
            f[j,4]:=f[j-1,3]+dp[x,1];
          end;
          ans:=max(f[sum,1],f[sum,3]);
          ans:=max(ans,f[sum,4]);
          answer:=answer+ans;
        end;
      writeln(answer);
    end;
    
    begin
      into;
      work;
    end.
    View Code
    因疲惫而轻易入眠,是对自己一天努力的最好褒奖。 要和泪子一起努力怀抱梦想对抗残酷的现实……
  • 相关阅读:
    oracle10G/11G官方迅雷下载地址合集(转载)
    Oracle数据库的登录以及常用数据导入查询
    Tomcat添加SSL网站证书配置
    SVN的安装与在IDEA中的配置
    01-Spring Boot配置文件详解
    微服务概况及注册中心搭建
    zk实现分布式锁
    ZooKeeper初识
    Reids集群知识
    redis初识
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4174741.html
Copyright © 2011-2022 走看看