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.
posted @ 2019-04-09 13:30  _ARFA  阅读(127)  评论(0编辑  收藏  举报