zoukankan      html  css  js  c++  java
  • bzoj1576 3694

    两道题目本质是一样的
    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
  • 相关阅读:
    T4 (Text Template Transformation Toolkit)
    GUI Design Studio
    51劳有所获 54务实青年
    [书目20110502]把时间当作朋友
    Rdlc子报表的动态添加
    [转]更新Android SDK到3.0版本时,遇到Failed to rename directory E:\android\tools to E:\android\temp\ToolPackage.old01问题
    JSON
    javascript 特征侦测技术
    IE的setAttribute bug
    将"类数组对象"转换成数组对象
  • 原文地址:https://www.cnblogs.com/phile/p/4473049.html
Copyright © 2011-2022 走看看