两道题目本质是一样的
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.
View Code

 

posted on 2015-01-01 19:42  acphile  阅读(248)  评论(0编辑  收藏  举报