首先考虑两个点的最优集合点,必然是在这两点间最短路径上
三个点的最优集合点,不难猜测,是在两两之间的LCA上取,
那到底取哪个呢?有一个偷懒的思维方法
由于最后的最优集合点唯一,如果有两个LCA相等,则一定是另外一个
当然事实也是这样
选定了集合点之后,设选的是a,b的LCA,ab到集合点的距离在LCA中可以求出,
但c点到集合点的距离呢?还要再做一次LCA……
所以比较烦
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 type link=^node; 2 node=record 3 po:longint; 4 next:link; 5 end; 6 point=^ask; 7 ask=record 8 po,num:longint; 9 next:point; 10 end; 11 12 var a:array[0..2000010] of point; 13 w:array[0..500010] of link; 14 al,b,d,fa,loc:array[0..500010] of longint; 15 ans:array[0..2000010] of longint; 16 c:array[0..500010,0..3] of longint; 17 v:array[0..500010] of boolean; 18 n,m,i,j,x,y,z:longint; 19 20 procedure add(x,y:longint); 21 var p:link; 22 begin 23 new(p); 24 p^.po:=y; 25 p^.next:=w[x]; 26 w[x]:=p; 27 end; 28 29 procedure que(x,y,p:longint); 30 var q:point; 31 begin 32 new(q); 33 q^.num:=p; 34 q^.po:=y; 35 q^.next:=a[x]; 36 a[x]:=q; 37 end; 38 39 function getf(x:longint):longint; 40 begin 41 if fa[x]<>x then fa[x]:=getf(fa[x]); 42 exit(fa[x]); 43 end; 44 45 procedure lca(x:longint); 46 var p:link; 47 q,pre:point; 48 y,e:longint; 49 begin 50 p:=w[x]; 51 v[x]:=true; 52 while p<>nil do 53 begin 54 y:=p^.po; 55 if not v[y] then 56 begin 57 d[y]:=d[x]+1; 58 lca(y); 59 fa[y]:=x; 60 end; 61 p:=p^.next; 62 end; 63 q:=a[x]; 64 while q<>nil do 65 begin 66 y:=q^.po; 67 if v[y] and (ans[q^.num]=0) then ans[q^.num]:=getf(y); 68 pre:=q; 69 q:=q^.next; 70 dispose(pre); 71 end; 72 end; 73 74 function get(i:longint):longint; 75 begin 76 if al[i]=1 then 77 exit(d[c[i,2]]+d[c[i,3]]-2*d[loc[i]]+d[loc[i]]+d[c[i,1]]-2*d[ans[i]]) 78 else if al[i]=2 then 79 exit(d[c[i,1]]+d[c[i,3]]-2*d[loc[i]]+d[loc[i]]+d[c[i,2]]-2*d[ans[i]]) 80 else exit(d[c[i,1]]+d[c[i,2]]-2*d[loc[i]]+d[loc[i]]+d[c[i,3]]-2*d[ans[i]]); 81 end; 82 83 begin 84 readln(n,m); 85 for i:=1 to n-1 do 86 begin 87 readln(x,y); 88 add(x,y); 89 add(y,x); 90 end; 91 for i:=1 to n do 92 fa[i]:=i; 93 for i:=1 to m do 94 begin 95 readln(x,y,z); 96 c[i,1]:=x; 97 c[i,2]:=y; 98 c[i,3]:=z; 99 que(x,y,i); 100 que(y,x,i); 101 que(y,z,i+m); 102 que(z,y,i+m); 103 que(x,z,i+2*m); 104 que(z,x,i+2*m); 105 end; 106 d[1]:=0; 107 lca(1); 108 for i:=1 to n do 109 begin 110 fa[i]:=i; 111 a[i]:=nil; 112 v[i]:=false; 113 d[i]:=0; 114 end; 115 for i:=1 to m do 116 begin 117 if ans[i]=ans[i+m] then 118 begin 119 loc[i]:=ans[i+2*m]; 120 al[i]:=2; 121 que(loc[i],c[i,2],i); 122 que(c[i,2],loc[i],i); 123 end 124 else if ans[i]=ans[i+2*m] then 125 begin 126 loc[i]:=ans[i+m]; 127 al[i]:=1; 128 que(loc[i],c[i,1],i); 129 que(c[i,1],loc[i],i); 130 end 131 else begin 132 loc[i]:=ans[i]; 133 al[i]:=3; 134 que(loc[i],c[i,3],i); 135 que(c[i,3],loc[i],i); 136 end; 137 ans[i]:=0; 138 end; 139 lca(1); 140 for i:=1 to m do 141 writeln(loc[i],' ',get(i)); 142 end.