题目大意:给张图,然后问你,如果某边的权值下降为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,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; 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. |
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.