# bzoj2125 3047

http://pan.baidu.com/s/1wzCpC

  1 type node=record
2        po,next,num:longint;
3      end;
4
5 var e,w:array[0..200010] of node;
6     dfn,low,p,q,mark,s,d,dis,dep,fa:array[0..10010] of longint;
7     anc:array[0..10010,0..20] of longint;
8     v:array[0..10010] of boolean;
9     st:array[0..1000010] of longint;
10     t,h,i,len,x,y,z,n,m,tot,qq:longint;
11
12 function min(a,b:longint):longint;
13   begin
14     if a>b then exit(b) else exit(a);
15   end;
16
18   begin
19     inc(len);
20     e[len].po:=y;
21     e[len].next:=p[x];
22     e[len].num:=z;
23     p[x]:=len;
24   end;
25
27   begin
28     inc(len);
29     w[len].po:=y;
30     w[len].next:=q[x];
31     q[x]:=len;
32   end;
33
34 procedure spfa;
35   var f,r,i,x,y:longint;
36   begin
37     f:=1;
38     r:=1;
39     st[1]:=1;
40     for i:=2 to n do  //d[]表示根节点到其他节点的最短路
41       d[i]:=2000000007;
42     while f<=r do
43     begin
44       x:=st[f];
45       i:=p[x];
46       v[x]:=false;
47       while i<>0 do
48       begin
49         y:=e[i].po;
50         if d[y]>d[x]+e[i].num then
51         begin
52           d[y]:=d[x]+e[i].num;
53           if not v[y] then
54           begin
55             inc(r);
56             st[r]:=y;
57             v[y]:=true;
58           end;
59         end;
60         i:=e[i].next;
61       end;
62       inc(f);
63     end;
64   end;
65
66 procedure get(x,y:longint);
67   begin
68     inc(tot);
69     while y<>x do
70     begin
71       mark[y]:=tot;  //环上节点（除最高点）标为同一颜色
73       y:=fa[y];
74     end;
75   end;
76
77 procedure dfs1(x:longint);
78   var i,y:longint;
79   begin
80     inc(h);
81     dfn[x]:=h;
82     low[x]:=h;
83     i:=p[x];
84     while i<>0 do
85     begin
86       y:=e[i].po;
87       if fa[x]<>y then
88       begin
89         if dfn[y]=0 then
90         begin
91           fa[y]:=x;
92           dis[y]:=dis[x]+e[i].num;  //dis[]表示得到的dfs树上根节点到节点的距离
93           dfs1(y);
94         end;
95         low[x]:=min(low[x],low[y]);
96         if low[y]>dfn[x] then
98       end;
99       i:=e[i].next;
100     end;
101     i:=p[x];
102     while i<>0 do
103     begin
104       y:=e[i].po;
105       if (dfn[y]>dfn[x]) and (fa[y]<>x) then
106       begin
107         get(x,y);  //处理环
108         s[tot]:=dis[y]-dis[x]+e[i].num;  //求这个环的长度
109       end;
110       i:=e[i].next;
111     end;
112   end;
113
114 procedure dfs2(x:longint);
115   var i,y:longint;
116   begin
117     for i:=1 to t do
118     begin
119       y:=anc[x,i-1];
120       if y<>0 then anc[x,i]:=anc[y,i-1] else break;
121     end;
122     i:=q[x];
123     while i<>0 do
124     begin
125       y:=w[i].po;
126       fa[y]:=x;
127       anc[y,0]:=x;
128       dep[y]:=dep[x]+1;  //在杨天树上的深度
129       dfs2(y);
130       i:=w[i].next;
131     end;
132   end;
133
134 function lca(x,y:longint):longint;
135   var i,p,a,b,z:longint;
136   begin
137     if x=y then exit(0);  //注意
138     if dep[x]<dep[y] then
139     begin
140       p:=x; x:=y; y:=p;
141     end;
142     a:=x;
143     b:=y;
144     p:=trunc(ln(dep[x])/ln(2));
145     if dep[a]>dep[b] then
146     begin
147       for i:=p downto 0 do
148         if dep[a]-1 shl i>=dep[b] then a:=anc[a,i];
149     end;
150     if a=b then exit(d[x]-d[a]);  //如果点a是点x的祖先那么a,x之间最短距离为d[x]-d[a]
151     for i:=p downto 0 do
152       if (anc[a,i]<>anc[b,i]) then
153       begin
154         a:=anc[a,i];
155         b:=anc[b,i];
156       end;
157     z:=fa[a];
158     if (mark[a]<>0) and (mark[a]=mark[b]) then  //最后提到环上两点要讨论
159     begin
160       p:=abs(dis[a]-dis[b]);
161       exit(d[x]-d[a]+d[y]-d[b]+min(p,s[mark[a]]-p));
162     end
163     else exit(d[x]+d[y]-2*d[z]);  //否则直接当树做
164   end;
165
166 begin
168   for i:=1 to m do
169   begin
173   end;
174   t:=trunc(ln(n)/ln(2));
175   spfa;
176   len:=0;
177   dfs1(1);
178   dfs2(1);
179   for i:=1 to qq do
180   begin
184 end.