P3534 [JZOJ/NOIP] 货车运输
给你一个图,每次询问给你 \(x,y\) 询问 \(x\) 到 \(y\) 的最大值。
你可以求最大生成树然后搞一搞 \(\texttt{LCA}\)。
运用重构树,树剖即可。时间复杂度 \(O(M \log N+M \ \alpha(n))\)。
Const
total=100000;
var
val,dep,top,size,father:array[-1..total*2] of longint;
input:array[-1..total*2,1..3] of longint;
dsu,bucket:array[-1..total*4] of longint;
son:array[-1..total*2,-1..2] of longint;
i,j,n,m,x,y,tail,root:longint;
function Get(x:longint):longint; begin if dsu[x]=x then exit(x) else begin Get:=Get(dsu[x]); dsu[x]:=Get; end; end;
procedure Sort(l,r:longint);
var i,j,s:longint;
begin
i:=l; j:=r; s:=input[(l+r) >> 1,3];
repeat
while (input[i,3]>s) do inc(i);
while (input[j,3]<s) do dec(j);
if i<=j then
begin
input[0]:=input[i]; input[i]:=input[j]; input[j]:=input[0];
inc(i); dec(j);
end;
until i>=j;
if i<r then Sort(i,r);
if j>l then Sort(l,j);
end;
procedure Dfs_1(x:longint);
var i:longint;
begin
size[x]:=1;
for i:=1 to 2 do
if (dep[son[x,i]]=0)and(son[x,i]<>0) then
begin
dep[son[x,i]]:=dep[x]+1;
father[son[x,i]]:=x;
Dfs_1(son[x,i]); inc(size[x],size[son[x,i]]);
if size[son[x,i]]>size[son[x,0]] then son[x,0]:=son[x,i];
end;
end;
procedure Dfs_2(x,centre:longint);
var i:longint;
begin
top[x]:=centre; if son[x,0]=0 then exit;
Dfs_2(son[x,0],centre);
for i:=1 to 2 do if (son[x,i]<>son[x,0]) then Dfs_2(son[x,i],son[x,i]);
end;
function Refer(x,y:longint):int64;
begin
while top[x]<>top[y] do if dep[top[x]]<dep[top[y]] then y:=father[top[y]] else x:=father[top[x]];
if dep[x]<dep[y] then exit(x) else exit(y);
end;
begin
read(n,m);
for i:=1 to n << 4 do dsu[i]:=i;
for i:=1 to m do
begin
for j:=1 to 3 do read(input[i,j]);
inc(bucket[input[i,1]]); inc(bucket[input[i,2]]);
end;
Sort(1,m);
for i:=1 to m do
begin
x:=input[i,1]; y:=input[i,2]; dsu[x]:=Get(x); dsu[y]:=Get(y);
if (dsu[x]=dsu[y]) then continue;
inc(n); val[n]:=input[i,3]; son[n,1]:=dsu[x]; son[n,2]:=dsu[y];
dsu[Get(x)]:=dsu[n]; dsu[Get(y)]:=dsu[n];
end;
for i:=1 to n do
begin
if father[i]<>0 then continue; root:=Get(i);
dep[root]:=1; father[root]:=root; Dfs_1(root); Dfs_2(root,root);
end;
read(m);
for i:=1 to m do
begin
read(x,y);
if (bucket[x]=0)or(bucket[y]=0)or(Get(x)<>Get(y)) then begin writeln(-1); continue; end;
writeln(val[Refer(x,y)]);
end;
end.
完结撒花!✿✿ヽ(゚▽゚)ノ✿