两道题目本质是一样的
bzoj1576我们先要用dij+heap处理出最短路径树和起点到每个点的最短路径
而bzoj3694已经给出了最短路径树,所以直接dfs即可
题目要求的是不走起点到每个点最短路径上的最后一条边的最短路径
首先我们考虑非树边的影响,对于一条非树边(u,v),加入到最短路径树中
必然会形成一个环,对于除了LCA(u,v)以外环上的点i,走边(u,v)的最短路径长度为d[u]+w(u,v)+d[v]-d[i]
显然我们只要穷举每个非树边,然后更新每个点可行的最短路径长度即可
裸的想法当然是可以用树链剖分+线段树来完成
但是我们有更好的想法,考虑我们用最小化d[u]+w(u,v)+d[v]即可
因此我们对每条边以d[u]+w(u,v)+d[v]为关键字从小到大排序
显然,按照这个顺序当前边更新的点一定已经是最优的
我们可以考虑用并查集维护,避免点被重复更新
1 const inf=2000000007; 2 type way=record 3 po,len,next:longint; 4 end; 5 node=record 6 loc,num:longint; 7 end; 8 9 var heap:array[0..100010] of node; 10 w,e:array[0..400010] of way; 11 can:array[0..400010] of boolean; 12 ans,fa,f,dep,from,d,p,where:array[0..100010] of longint; 13 j,i,n,m,t,x,y,z:longint; 14 15 procedure change(var a,b:node); 16 var c:node; 17 begin 18 c:=a; 19 a:=b; 20 b:=c; 21 end; 22 23 procedure swap(var a,b:longint); 24 var c:longint; 25 begin 26 c:=a; 27 a:=b; 28 b:=c; 29 end; 30 31 procedure sort(l,r: longint); 32 var i,j: longint; 33 x,y:way; 34 begin 35 i:=l; 36 j:=r; 37 x:=e[(l+r) shr 1]; 38 repeat 39 while e[i].len<x.len do inc(i); 40 while x.len<e[j].len do dec(j); 41 if not(i>j) then 42 begin 43 y:=e[i]; 44 e[i]:=e[j]; 45 e[j]:=y; 46 inc(i); 47 j:=j-1; 48 end; 49 until i>j; 50 if l<j then sort(l,j); 51 if i<r then sort(i,r); 52 end; 53 54 function getf(x:longint):longint; 55 begin 56 if f[x]<>x then f[x]:=getf(f[x]); 57 exit(f[x]); 58 end; 59 60 procedure add(x,y,z:longint); 61 begin 62 inc(t); 63 w[t].po:=y; 64 w[t].next:=p[x]; 65 w[t].len:=z; 66 p[x]:=t; 67 end; 68 69 procedure up(i:longint); 70 var j,x,y:longint; 71 begin 72 j:=i shr 1; 73 while j>0 do 74 begin 75 if heap[i].num<heap[j].num then 76 begin 77 x:=heap[i].loc; 78 y:=heap[j].loc; 79 where[x]:=j; 80 where[y]:=i; 81 change(heap[i],heap[j]); 82 i:=j; 83 j:=i shr 1; 84 end 85 else break; 86 end; 87 end; 88 89 procedure sift(i:longint); 90 var j,x,y:longint; 91 begin 92 j:=i shl 1; 93 while j<=t do 94 begin 95 if (j<t) and (heap[j].num>heap[j+1].num) then inc(j); 96 if heap[i].num>heap[j].num then 97 begin 98 x:=heap[i].loc; 99 y:=heap[j].loc; 100 where[x]:=j; 101 where[y]:=i; 102 change(heap[i],heap[j]); 103 i:=j; 104 j:=i shl 1; 105 end 106 else break; 107 end; 108 end; 109 110 procedure dij; 111 var i,j,mid,x,y:longint; 112 begin 113 fillchar(from,sizeof(from),255); 114 d[1]:=0; 115 where[1]:=1; 116 heap[1].loc:=1; 117 heap[1].num:=0; 118 for i:=2 to n do 119 begin 120 where[i]:=i; 121 d[i]:=inf; 122 heap[i].num:=inf; 123 heap[i].loc:=i; 124 end; 125 for i:=1 to n-1 do 126 begin 127 x:=heap[1].loc; 128 mid:=heap[1].num; 129 y:=heap[t].loc; 130 where[y]:=1; 131 change(heap[1],heap[t]); 132 dec(t); 133 sift(1); 134 j:=p[x]; 135 while j<>-1 do 136 begin 137 y:=w[j].po; 138 if d[y]>mid+w[j].len then 139 begin 140 fa[y]:=x; 141 dep[y]:=dep[x]+1; 142 d[y]:=mid+w[j].len; 143 if from[y]<>-1 then 144 begin 145 can[from[y]]:=false; 146 can[from[y] xor 1]:=false; 147 end; 148 from[y]:=j; 149 can[j]:=true; 150 can[j xor 1]:=true; 151 heap[where[y]].num:=d[y]; 152 up(where[y]); 153 end; 154 j:=w[j].next; 155 end; 156 end; 157 end; 158 159 procedure calc(x,y,z:longint); 160 var px,py:longint; 161 begin 162 px:=-1; 163 py:=-1; 164 while getf(x)<>getf(y) do 165 begin 166 if dep[x]<dep[y] then 167 begin 168 swap(x,y); 169 swap(px,py); 170 end; 171 if ans[x]=-1 then 172 begin 173 ans[x]:=z-d[x]; 174 if px<>-1 then f[px]:=x; 175 end 176 else 177 if px<>-1 then f[px]:=getf(x); 178 px:=getf(x); 179 x:=fa[px]; 180 end; 181 end; 182 183 begin 184 t:=-1; 185 fillchar(p,sizeof(p),255); 186 readln(n,m); 187 for i:=1 to m do 188 begin 189 readln(x,y,z); 190 add(x,y,z); 191 add(y,x,z); 192 end; 193 t:=n; 194 dij; 195 t:=0; 196 for i:=1 to n do 197 begin 198 j:=p[i]; 199 f[i]:=i; 200 while j<>-1 do 201 begin 202 if not can[j] then 203 begin 204 inc(t); 205 e[t].po:=i; 206 e[t].next:=w[j].po; 207 e[t].len:=w[j].len+d[i]+d[w[j].po]; 208 can[j xor 1]:=true; 209 end; 210 j:=w[j].next; 211 end; 212 end; 213 sort(1,t); 214 fillchar(ans,sizeof(ans),255); 215 for i:=1 to t do 216 calc(e[i].po,e[i].next,e[i].len); 217 for i:=2 to n do 218 writeln(ans[i]); 219 end.