zoukankan      html  css  js  c++  java
  • bzoj3242

    如果是树,那么一定选择树的直径的中点

    套了个环?裸的想法显然是断开环,然后求所有树的直径的最小值

    环套树dp的一般思路,先把环放到根,把环上点下面的子树dp出来,然后再处理环上的情况

    设f[i]表示以i为根的子树向下延伸的最长链长度

    我们把环上的点扩展一倍,用前缀和维护环上的边权

    依次枚举断点,则对直径影响就是max(s[j]-s[i]+f[i]+f[j])

    分别维护max(s[j]+f[j])和max(f[i]-s[i])

    注意i≠j,所以我们还要维护一个次小值

      1 type node=record
      2        po,next,num:longint;
      3      end;
      4      link=record
      5        loc:longint;
      6        mx:int64;
      7      end;
      8 
      9 var tree:array[0..200010*4,1..2] of link;
     10     e:array[0..200010] of node;
     11     cut:array[0..200010] of boolean;
     12     a,b,p,fa:array[0..200010] of longint;
     13     v:array[0..200010] of boolean;
     14     f,s:array[0..200010] of int64;
     15     i,len,n,t,x,y,z:longint;
     16     ll,ans,lin:int64;
     17     l1,l2,tp:link;
     18 
     19 function max(a,b:int64):int64;
     20   begin
     21     if a>b then exit(a) else exit(b);
     22   end;
     23 
     24 function min(a,b:int64):int64;
     25   begin
     26     if a>b then exit(b) else exit(a);
     27   end;
     28 
     29 procedure add(x,y,z:longint);
     30   begin
     31     inc(len);
     32     e[len].po:=y;
     33     e[len].next:=p[x];
     34     e[len].num:=z;
     35     p[x]:=len;
     36   end;
     37 
     38 procedure find(x:longint);
     39   var i,y,h:longint;
     40   begin
     41     i:=p[x];
     42     while i<>-1 do
     43     begin
     44       y:=e[i].po;
     45       if not cut[i] then
     46       begin
     47         if fa[y]<>0 then
     48         begin
     49           h:=x;
     50           while h<>y do
     51           begin
     52             inc(t);
     53             a[t]:=h;
     54             b[t]:=f[h];
     55             h:=fa[h];
     56           end;
     57           inc(t);
     58           a[t]:=h;
     59           b[t]:=e[i].num;
     60           break;
     61         end
     62         else begin
     63           cut[i]:=true;
     64           cut[i xor 1]:=true;
     65           fa[y]:=x;
     66           f[y]:=e[i].num;
     67           find(y);
     68         end;
     69       end;
     70       if t<>0 then break;
     71       i:=e[i].next;
     72     end;
     73   end;
     74 
     75 procedure dfs(x:longint);
     76   var i,y:longint;
     77   begin
     78     v[x]:=true;
     79     f[x]:=0;
     80     i:=p[x];
     81     while i<>-1 do
     82     begin
     83       y:=e[i].po;
     84       if not v[y] then
     85       begin
     86         dfs(y);
     87         lin:=max(lin,f[y]+f[x]+e[i].num);
     88         f[x]:=max(f[x],f[y]+e[i].num);
     89       end;
     90       i:=e[i].next;
     91     end;
     92   end;
     93 
     94 procedure update(var c:link; a:link; b:link);
     95   begin
     96     c.mx:=a.mx;
     97     c.loc:=a.loc;
     98     if c.mx<b.mx then
     99     begin
    100       c.loc:=b.loc;
    101       c.mx:=b.mx;
    102     end;
    103   end;
    104 
    105 procedure build(i,l,r:longint);
    106   var m:longint;
    107   begin
    108     if l=r then
    109     begin
    110       tree[i,1].mx:=f[a[l]]+s[l];
    111       tree[i,1].loc:=l;
    112       tree[i,2].mx:=f[a[l]]-s[l];
    113       tree[i,2].loc:=l;
    114     end
    115     else begin
    116       m:=(l+r) shr 1;
    117       build(i*2,l,m);
    118       build(i*2+1,m+1,r);
    119       update(tree[i,1],tree[i*2,1],tree[i*2+1,1]);
    120       update(tree[i,2],tree[i*2,2],tree[i*2+1,2]);
    121     end;
    122   end;
    123 
    124 function ask(i,l,r,w,x,y:longint):link;
    125   var m:longint;
    126       s,s1,s2:link;
    127   begin
    128     if (x<=l) and (y>=r) then exit(tree[i,w])
    129     else begin
    130       m:=(l+r) shr 1;
    131       if x>m then exit(ask(i*2+1,m+1,r,w,x,y));
    132       if y<=m then exit(ask(i*2,l,m,w,x,y));
    133       s1:=ask(i*2,l,m,w,x,y);
    134       s2:=ask(i*2+1,m+1,r,w,x,y);
    135       update(s,s1,s2);
    136       exit(s);
    137     end;
    138   end;
    139 
    140 begin
    141   len:=-1;
    142   fillchar(p,sizeof(p),255);
    143   readln(n);
    144   for i:=1 to n do
    145   begin
    146     readln(x,y,z);
    147     add(x,y,z);
    148     add(y,x,z);
    149   end;
    150   fa[1]:=-1;
    151   find(1);
    152   for i:=1 to t do
    153   begin
    154     v[a[i]]:=true;
    155     a[i+t]:=a[i];
    156     b[i+t]:=b[i];
    157   end;
    158   for i:=1 to 2*t do
    159     s[i]:=s[i-1]+b[i-1];
    160   for i:=1 to t do
    161     dfs(a[i]);
    162   build(1,1,2*t);
    163   ans:=1000000000000010;
    164   for i:=1 to t do
    165   begin
    166     l1:=ask(1,1,2*t,1,i+1,i+t);
    167     l2:=ask(1,1,2*t,2,i+1,i+t);
    168     if l1.loc=l2.loc then
    169     begin
    170       ll:=0;
    171       if l1.loc>i+1 then
    172       begin
    173         tp:=ask(1,1,2*t,2,i+1,l1.loc-1);
    174         ll:=max(ll,l1.mx+tp.mx);
    175       end;
    176       if l2.loc<i+t then
    177       begin
    178         tp:=ask(1,1,2*t,1,l2.loc+1,i+t);
    179         ll:=max(ll,l2.mx+tp.mx);
    180       end;
    181       ans:=min(ans,max(ll,lin));
    182     end
    183     else ans:=min(ans,max(l1.mx+l2.mx,lin));
    184   end;
    185   writeln(ans/2:0:1);
    186 end.
    View Code
  • 相关阅读:
    codeforces #586 ABC~D
    codeforces #585 div2 ABCD
    编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现
    codeforces #599 div2 ABCD
    codeforces #598 div3 ABCDF
    codeforces #587 div3 ABCDE
    codeforces educational round 73 div2 ABCD
    Mud Puddles ( bfs )
    2019牛客多校第十场B.Coffee Chicken(递归)
    2019牛客多校训练第七场A. String(暴力)
  • 原文地址:https://www.cnblogs.com/phile/p/4610436.html
Copyright © 2011-2022 走看看