• bzoj1487: [HNOI2009]无归岛


    依然环套树……不过那个状态转移方程好写多了……

    无聊写了滚动数组结果……hehe(又是一节课的牺牲)……

    type
      arr=record
        toward,next:longint;
      end;
    
    const
      maxm=1000000;
      maxn=600000;
    
    var
      edge:array[0..maxm]of arr;
      first,dfn,low,dep,num,value,fa:array[0..maxn]of longint;
      f:array[0..maxn,0..1]of longint;
      tot,n,m,time:longint;
    
    function max(x,y:longint):longint;
    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 dp(x,root:longint);
    var
      i,sum,j,l,k:longint;
      dp:array[0..1,0..1]of longint;
    begin
      sum:=dep[x]-dep[root]+1;
      i:=x;
      while sum>0 do begin
        num[sum]:=i;
        i:=fa[i];
        dec(sum);
      end;
      sum:=dep[x]-dep[root]+1;
      dp[0,1]:=f[num[sum],1];
      dp[0,0]:=f[num[sum],0];
      l:=0;
      for i:=sum-1 downto 2 do begin
        j:=num[i];
        dp[1-l,0]:=max(dp[l,0],dp[l,1])+f[j,0];
        dp[1-l,1]:=dp[l,0]+f[j,1];
        l:=1-l;
      end;
      k:=max(dp[l,1],dp[l,0])+f[root,0]; //记住!!这里不能直接去更新f[root,0]因为下一步就要用到原始值233333
      l:=0;
      dp[0,1]:=f[root,1];
      dp[0,0]:=f[root,0];
      for i:=2 to sum do begin
        j:=num[i];
        dp[1-l,0]:=max(dp[l,0],dp[l,1])+f[j,0];
        dp[1-l,1]:=dp[l,0]+f[j,1];
        l:=1-l;
      end;
      f[root,0]:=k;
      f[root,1]:=dp[l,0];
    end;
    
    procedure tarjan(x:longint);
    var
      i,too:longint;
    begin
      inc(time);
      dfn[x]:=time;
      low[x]:=time;
      i:=first[x];
      f[x,1]:=value[x];
      while i>0 do begin
        too:=edge[i].toward;
        if too<>fa[x] then begin
          if dfn[too]=0 then begin
            fa[too]:=x;
            dep[too]:=dep[x]+1;
            tarjan(too);
            if low[x]>low[too] then low[x]:=low[too];
          end
          else
            if dfn[too]<low[x] then low[x]:=dfn[too];
          if dfn[x]<low[too] then begin
              f[x,1]:=f[x,1]+f[too,0];
              f[x,0]:=f[x,0]+max(f[too,0],f[too,1]);
            end;
        end;
        i:=edge[i].next;
      end;
      i:=first[x];
      while i>0 do begin
        too:=edge[i].toward;
        if (fa[too]<>x) and (dfn[x]<dfn[too]) then begin
          dp(too,x);
        end;
        i:=edge[i].next;
      end;
    end;
    
    procedure into;
    var
      i,j,k:longint;
    begin
      readln(n,m);
      for i:=1 to m do begin
        read(j,k);
        addedge(j,k);
        addedge(k,j);
      end;
      for i:=1 to n do read(value[i]);
    end;
    
    procedure work;
    begin
      time:=0;
      dep[1]:=1;
      tarjan(1);
      writeln(max(f[1,0],f[1,1]));
    end;
    
    begin
      into;
      work;
    
    end.
    View Code
    因疲惫而轻易入眠,是对自己一天努力的最好褒奖。 要和泪子一起努力怀抱梦想对抗残酷的现实……
  • 相关阅读:
    414. Third Maximum Number 第三大的数字
    java 正则表达式
    将含有逻辑运算符的字符串解析为逻辑符号
    ora-01830:日期格式图片在转换整个输入字符串之前结束
    mysql的字符拼接
    oracle执行计划详解
    oracle获取执行计划及优缺点 详解
    kmp算法中的nextval实例解释
    kmp算法中的next数组实例解释
    哈夫曼实例解释(哈夫曼编码)
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4181073.html
Copyright © 2020-2023  润新知