[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.