## 【NOIP2016练习&BZOJ2125】T3 sp （树上倍增，最短路）

只会80，正解听说是仙人掌

对于80每个询问的最优解必定是一棵树或一棵树+一条边，因为环的个数<=1

倍增LCA求距离，枚举树上加哪条边即可

  1 var f,g:array[1..100000,0..20]of longint;
3     n,i,tx,ty,tz,ans,w,tot,m,q,x,y,j:longint;
4
5 function min(x,y:longint):longint;
6 begin
7  if x<y then exit(x);
8  exit(y);
9 end;
10
12 begin
13  inc(tot);
15  vet[tot]:=b;
16  len[tot]:=c;
18 end;
19
20 procedure swap(var x,y:longint);
21 var t:longint;
22 begin
23  t:=x; x:=y; y:=t;
24 end;
25
26 function lca(x,y:longint):longint;
27 var i,d:longint;
28 begin
29  if dep[x]<dep[y] then swap(x,y);
30  d:=dep[x]-dep[y];
31  for i:=0 to 14 do
32   if d and (1<<i)>0 then x:=f[x,i];
33  for i:=14 downto 0 do
34   if f[x,i]<>f[y,i] then
35   begin
36    x:=f[x,i]; y:=f[y,i];
37   end;
38  if x=y then exit(x);
39  exit(f[x,0]);
40 end;
41
42 function clac(x,y:longint):longint;
43 var i,d:longint;
44 begin
45  if dep[x]<dep[y] then swap(x,y);
46  d:=dep[x]-dep[y];
47  clac:=0;
48  for i:=0 to 14 do
49   if d and (1<<i)>0 then
50   begin
51    clac:=clac+g[x,i];
52    x:=f[x,i];
53   end;
54 end;
55
57 var t:longint;
58 begin
59  t:=lca(x,y);
60  exit(clac(x,t)+clac(y,t));
61 end;
62
63 function find(k:longint):longint;
64 begin
65  if fa[k]<>k then fa[k]:=find(fa[k]);
66  exit(fa[k]);
67 end;
68
69 procedure dfs(u,pre:longint);
70 var i,e,v:longint;
71 begin
72  for i:=1 to 14 do
73  begin
74   if dep[u]<1<<i then break;
75   f[u,i]:=f[f[u,i-1],i-1];
76   g[u,i]:=g[u,i-1]+g[f[u,i-1],i-1];
77  end;
79  while e<>0 do
80  begin
81   v:=vet[e];
82   if v<>pre then
83   begin
84    dep[v]:=dep[u]+1;
85    f[v,0]:=u; g[v,0]:=len[e];
86    dfs(v,u);
87   end;
88   e:=next[e];
89  end;
90 end;
91
92 begin
93  assign(input,'sp.in'); reset(input);
94  assign(output,'sp.out'); rewrite(output);
96  for i:=1 to n do fa[i]:=i;
97  for i:=1 to m do
98  begin
100   x:=find(tx); y:=find(ty);
101   if x<>y then
102   begin
103    fa[y]:=x;
106   end
107    else begin inc(w); a[w]:=tx; b[w]:=ty; c[w]:=tz; end;
108  end;
109  dfs(1,-1);
110  for i:=1 to q do
111  begin
114   for j:=1 to w do
115   begin
118   end;
119   writeln(ans);
120  end;
121  close(input);
122  close(output);
123 end.

posted on 2016-11-03 16:24  myx12345  阅读(270)  评论(0编辑  收藏

• 随笔 - 617
• 文章 - 0
• 评论 - 5
• 引用 - 0