const maxN=1000; const maxK=1000; var {zadání} K,N:integer; obeti:array [1..maxN] of integer; hrany:array [1..maxK,1..2] of integer; {pro průchody} byl:array [1..maxN] of boolean; {značka pro DFS} sousedi:array [1..(2*maxK)] of integer; {tabulka sousedů} poc_hran:array [1..maxN] of integer; {počet zájmových hran z vrcholu} procedure projdi(v:integer;sou:boolean); var i:integer; begin if byl[v] then exit; {byl jsem tu už?} byl[v]:=true; projdi(obeti[v],sou); {projdi se po kružnici...} if not sou then exit; {mám jít i podle pole sousedi?} for i:=poc_hran[v]+1 to poc_hran[v+1] do projdi(sousedi[i],sou); {rekurze...} end; var i,a,b:integer; kruznic,komponent:integer; begin kruznic:=0; komponent:=0; read(N); {nejprve načtu oběti (kružnice v grafu)} for i:=1 to N do begin read(a); obeti[i]:=a; {načtu oběti} byl[i]:=false; {...a zároveň inicializuji} poc_hran[i]:=0; end; for i:=1 to N do {projdu kružnice DFS} if not byl[i] then begin projdi(i,false); {projdi bez pole sousedi} inc(kruznic); end; for i:=1 to N do byl[i]:=false; {uklid} read(K); {a nyní se zájmovými hranami:} for i:=1 to K do begin read(a,b); {načtu další hrany} hrany[i,1]:=a; inc(poc_hran[a]); hrany[i,2]:=b; inc(poc_hran[b]); end; {z počtu hran vyrobím nasčítáním indexy do velkého pole sousedi} {to obsahuje před poc_hran[i] dost místa na všechny hrany z a do i} for i:=2 to N do inc(poc_hran[i],poc_hran[i-1]); poc_hran[N+1]:=poc_hran[N]; for i:=1 to K do begin a:=hrany[i,1]; b:=hrany[i,2]; {zapíšu souseda na volné místo do sousedi[] a posunu ukazovadlo} sousedi[poc_hran[a]]:=b; dec(poc_hran[a]); sousedi[poc_hran[b]]:=a; dec(poc_hran[b]); end; for i:=1 to N do {projdu kružnice i zájmové hrany DFS} if not byl[i] then begin projdi(i,true); {nyní i s polem sousedi} inc(komponent); end; writeln('Je potřeba ',kruznic-komponent,' přehození.'); end.