bzoj2791

每个顶点有且仅有一条出边是什么意思呢

类似一棵树,树上的边都是由儿子指向父亲的,并且这个东西带着一个环

也就是一个个有向环套有向树……

这题还是比较简单的,把环作为根然后类似lca做即可,注意细节的panding

  1 type node=record
  2        po,next:longint;
  3      end;
  4 
  5 var e:array[0..500010] of node;
  6     s,p,w,c,be,d,q:array[0..500010] of longint;
  7     v:array[0..500010] of boolean;
  8     anc:array[0..500010,0..20] of longint;
  9     t,f,r,n,m,len,i,x,y,a,b:longint;
 10 
 11 function max(a,b:longint):longint;
 12   begin
 13     if a>b then exit(a) else exit(b);
 14   end;
 15 
 16 function min(a,b:longint):longint;
 17   begin
 18     if a>b then exit(b) else exit(a);
 19   end;
 20 
 21 procedure swap(var a,b:longint);
 22   var c:longint;
 23   begin
 24     c:=a;
 25     a:=b;
 26     b:=c;
 27   end;
 28 
 29 procedure add(x,y:longint);
 30   begin
 31     inc(len);
 32     e[len].po:=y;
 33     e[len].next:=p[x];
 34     p[x]:=len;
 35   end;
 36 
 37 procedure bfs;
 38   var x,i,y:longint;
 39   begin
 40     f:=1;
 41     while f<=r do
 42     begin
 43       x:=q[f];
 44       for i:=1 to 20 do
 45       begin
 46         y:=anc[x,i-1];
 47         if y<>0 then anc[x,i]:=anc[y,i-1] else break;
 48       end;
 49       i:=p[x];
 50       while i<>0 do
 51       begin
 52         y:=e[i].po;
 53         if not v[y] then
 54         begin
 55           d[y]:=d[x]+1;
 56           anc[y,0]:=x;
 57           be[y]:=t;
 58           inc(r);
 59           q[r]:=y;
 60           v[y]:=true;
 61         end;
 62         i:=e[i].next;
 63       end;
 64       inc(f);
 65     end;
 66   end;
 67 
 68 procedure lca(x,y:longint);
 69   var i,num,a1,b1,a2,b2:longint;
 70   begin
 71     a:=0; b:=0;
 72     if d[x]>d[y] then
 73       for i:=20 downto 0 do
 74         if d[x]-1 shl i>=d[y] then
 75         begin
 76           x:=anc[x,i];
 77           a:=a+1 shl i;
 78         end;
 79 
 80     if d[y]>d[x] then
 81       for i:=20 downto 0 do
 82         if d[y]-1 shl i>=d[x] then
 83         begin
 84           y:=anc[y,i];
 85           b:=b+1 shl i;
 86         end;
 87 
 88     if x=y then exit;
 89     for i:=20 downto 0 do
 90       if (anc[x,i]<>anc[y,i]) then
 91       begin
 92         x:=anc[x,i]; a:=a+1 shl i;
 93         y:=anc[y,i]; b:=b+1 shl i;
 94       end;
 95 
 96     if (anc[x,0]=anc[y,0]) and (anc[x,0]<>0) then
 97     begin
 98       inc(a); inc(b);
 99       exit;
100     end;
101     num:=s[be[x]];
102     if c[x]>c[y] then a1:=a+num-c[x]+c[y] else a1:=a+c[y]-c[x];
103     b1:=b;
104     a2:=a;
105     if c[x]<c[y] then b2:=b+num-c[y]+c[x] else b2:=b+c[x]-c[y];
106     if max(a1,b1)=max(a2,b2) then
107     begin
108       if (min(a1,b1)>min(a2,b2)) or (min(a1,b1)=min(a2,b2)) and (a1<b1) then
109       begin
110         a:=a2;
111         b:=b2;
112       end
113       else begin
114         a:=a1;
115         b:=b1;
116       end;
117     end
118     else if max(a1,b1)>max(a2,b2) then
119     begin
120       a:=a2;
121       b:=b2;
122     end
123     else begin
124       a:=a1;
125       b:=b1;
126     end;
127   end;
128 
129 begin
130   readln(n,m);
131   for i:=1 to n do
132   begin
133     read(w[i]);
134     add(w[i],i);
135   end;
136 
137   for i:=1 to n do
138     if be[i]=0 then
139     begin
140       inc(t);
141       be[i]:=t;
142       x:=i;
143       while true do
144       begin
145         x:=w[x];
146         if be[x]=t then break;
147         be[x]:=t;
148       end;
149       y:=x;
150       r:=0;
151       repeat
152         inc(s[t]);
153         c[y]:=s[t];
154         inc(r);
155         q[r]:=y;
156         v[y]:=true;
157         y:=w[y];
158       until y=x;
159       bfs;
160     end;
161 
162   for i:=1 to m do
163   begin
164     readln(x,y);
165     if be[x]<>be[y] then
166     begin
167       writeln('-1 -1');
168       continue;
169     end;
170     lca(x,y);
171     writeln(a,' ',b);
172   end;
173 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4552804.html