[Accepted][POJ1986]Tarjan求lca
嗯,这个就作为Tarjan求lca的模板了。
网上很多解法用了ancestor数组,其实不需要,只要在合并并查集时记得将叶子合并到树根就行了。
注意不联通情况下的处理。
数组要开2N。
| Problem: 1986 | User: HTwood |
| Memory: 4308K | Time: 141MS |
| Language: Pascal | Result: Accepted |
program graph;
Type
rec=record
e,w,next:longint;
end;
rec2=record
e,num,next:longint;
end;
rec3=record
s,e:longint;
end;
Var
a:array[0..100000] of rec;
b,c,f,ans,l:array[0..100000] of longint;
que:array[0..100000] of rec3;
q:array[0..100000] of rec2;
v:array[0..100000] of boolean;
ch:char;
n,m,i,ss,ee,ww,top,top2,top3:longint;
Procedure fopen;
begin
assign(input,'graph.in');
assign(output,'graph.out');
reset(input);
rewrite(output);
end;
Procedure fclose;
begin
close(input);
close(output);
end;
Procedure Add(ss,ee,ww:longint);
begin
inc(top);
with a[top] do
begin
e:=ee;
w:=ww;
next:=b[ss];
end;
b[ss]:=top;
end;
Procedure Add2(ss,ee,pnum:longint);
begin
inc(top2);
with q[top2] do
begin
e:=ee;
num:=pnum;
next:=c[ss];
end;
c[ss]:=top2;
end;
Procedure AddQ(ss,ee:longint);
begin
inc(top3);
que[top3].s:=ss;
que[top3].e:=ee;
end;
Procedure init;
var
i:longint;
begin
for i:=1 to n do
f[i]:=i;
fillchar(v,sizeof(v),false);
end;
Function find(P:longint):longint;inline;
var
x:longint;
begin
x:=p;
while f[x]<>x do x:=f[x];
f[p]:=x;
exit(x);
end;
Procedure Dfs(P:longint);
var
g:longint;
x:rec;
y:rec2;
begin
//writeln('dfs(',p,')');
f[p]:=p;
v[p]:=true;
g:=c[p];
while g>0 do
begin
y:=q[g];
g:=y.next;
//writeln('p=',p,' Y=',y.e);
if v[y.e] then
ans[y.num]:=find(y.e);
end;
g:=b[p];
while g>0 do
begin
x:=a[g];
g:=x.next;
if not v[x.e] then
begin
l[x.e]:=l[p]+x.w;
dfs(x.e);
f[find(x.e)]:=p;
end;
end;
end;
begin
readln(n,m);
top:=0;top2:=0;
top3:=0;
for i:=1 to m do
begin
read(ss,ee,ww);
readln(ch);
Add(ss,ee,ww);
Add(ee,ss,ww);
end;
readln(m);
for i:=1 to m do
begin
readln(ss,ee);
AddQ(ss,ee);
Add2(ss,ee,i);
Add2(ee,ss,i);
end;
init;
for i:=1 to n do if not v[i] then Dfs(i);
for i:=1 to m do
writeln(l[que[i].s]+l[que[i].e]-2*l[ans[i]]);
end.

浙公网安备 33010602011771号