题目大意:给张图,然后问你,如果某边的权值下降为V,那么这个边有无可能在最小生成树中呢?节点数≤1000,边数≤100000,询问数≤100000。 由于网上唯一的标程是java,所以讲一下这道题。 可知,最小生成树上两点间路径上最大边为这两点间所有路径中路径上最大边最小的边,如果一条边可以出现在最小生成树中,其边权必小于等于两点间路径上最大边,于是我们只需快速找出这条边,即可回答。 又是一个结论这种边即两点在最小顺序生成树中的lca(郭华阳论文),所以求一遍最小生成树,在每次跑一边lca。 因为今天做了一道倍增题,所以这道题的lca我也是用倍增算法,先倍增到同一深度,在同时向上倍增,如果过了就减小倍数。
|
var lca,n,m,s1,q:longint;
t,l,r,p,w,ww:array[1..300000]of longint;
b,lson,rson:array[1..300000]of longint;
f:array[1..300000,0..30]of longint;
d,st:array[1..300000]of longint;
procedure qsort(ll,rr:longint);
var i,j,x,c:longint;
begin
i:=ll;j:=rr;x:=w[(ll+rr)>>1];
repeat
while w[i]<x do inc(i);
while x<w[j] do dec(j);
if not(i>j) then begin
c:=w[i];w[i]:=w[j];w[j]:=c;
c:=l[i];l[i]:=l[j];l[j]:=c;
c:=r[i];r[i]:=r[j];r[j]:=c;
c:=p[i];p[i]:=p[j];p[j]:=c;
inc(i);dec(j)
end
until i>j;
if i<rr then qsort(i,rr);
if ll<j then qsort(ll,j)
end;
procedure link(root,l,r:longint);
begin
lson[root]:=l;rson[root]:=r;
f[l,0]:=root;f[r,0]:=root
end;
procedure bfs(s:longint);
var h,r,ne:longint;
begin
fillchar(st,sizeof(st),0);fillchar(d,sizeof(d),127);
h:=0;r:=1;st[1]:=s;d[s]:=0;
repeat
inc(h);ne:=st[h];
if lson[ne]<>0 then begin d[lson[ne]]:=d[ne]+1;inc(r);st[r]:=lson[ne] end;
if rson[ne]<>0 then begin d[rson[ne]]:=d[ne]+1;inc(r);st[r]:=rson[ne] end
until h>=r
end;
procedure origin;
var i,k:longint;
begin
for k:=1 to 30 do
for i:=1 to s1-1 do if d[i]>=1<<k then
f[i,k]:=f[f[i,k-1],k-1]
end;
function ask(l,r:longint):longint;
var e,i,k,p,dis:longint;
begin
if d[r]>d[l] then begin e:=l;l:=r;r:=e end;
dis:=d[l]-d[r];p:=0;
while dis<>0 do begin
if dis and 1=1 then l:=f[l,p];
inc(p);
dis:=dis>>1
end;
k:=0;
{while l<>r do begin
if (f[l,k]<>f[r,k])or((f[l,k]=f[r,k])and(k=0)) then begin
l:=f[l,k];r:=f[r,k];inc(k)
end
else dec(k)
end;}
for i:=30 downto 0 do
if (f[l,i]<>f[r,i]) then begin
l:=f[l,i];
r:=f[r,i];
end;
l:=f[l,0];r:=f[r,0];
ask:=ww[l]
end;
function find(x:longint):longint;
begin
if b[x]<>x then b[x]:=find(b[x]);find:=b[x]
end;
procedure init;
var i,ll,rr,x,y,z:longint;
begin
readln(n,m,q);
for i:=1 to m do begin
readln(x,y,z);
l[i]:=x;r[i]:=y;w[i]:=z;
p[i]:=i
end;
qsort(1,m);
for i:=1 to n+m do b[i]:=i;
s1:=n;
fillchar(f,sizeof(f),0);
for i:=1 to m do begin
ll:=find(l[i]);rr:=find(r[i]);
if ll<>rr then begin
inc(s1);
b[ll]:=s1;b[rr]:=s1;ww[s1]:=w[i];
link(s1,ll,rr)
end
end;
for i:=1 to m do t[p[i]]:=i;
bfs(s1);
origin;
for i:=1 to q do begin
readln(x,y);
x:=t[x];
lca:=ask(l[x],r[x]);
if y<=lca then writeln('Yes') else writeln('No')
end;
end;
begin
init;
end.