如果是树,那么一定选择树的直径的中点
套了个环?裸的想法显然是断开环,然后求所有树的直径的最小值
环套树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.