この問題を解決しようとしました 問題の説明 与えられたグラフにサイクルがあるかどうか(ツリーであるかどうか)を確認するのが正しい考えのようです。しかし、私のコードはテスト7(常に制限時間を超えています)に合格できませんでした。これを高速化する方法はありますか?DFSを使用しました。はい、ようやく受け入れられました。問題は、各頂点のdfsであり、これは不要です。dfs関数は次のようになります。
function dfs(idx: integer; id: integer): boolean;
begin
if (visited[idx] = id) then
begin
Result := false;
Exit;
end;
if (tree[idx] <> 0) then
begin
visited[idx] := id;
Result := dfs(tree[idx], id);
Exit;
end;
Result := true;
end;
program Project2;
{$APPTYPE CONSOLE}
var
i, m, j, n, k: integer;
tree: array [1 .. 25001] of integer;
visited: array [1 .. 25001] of boolean;
function dfs(idx: integer): boolean;
label
fin;
var
buf: array[1 .. 25001] of integer;
i, cnt: integer;
begin
cnt := 1;
while (true) do
begin
if (visited[idx]) then
begin
Result := false;
goto fin;
end;
if (tree[idx] <> 0) then
begin
visited[idx] := true;
buf[cnt] := idx;
Inc(cnt);
idx := tree[idx];
end
else
begin
break;
end;
end;
Result := true;
fin:
for i := 1 to cnt - 1 do
begin
visited[buf[i]] := false;
end;
end;
function chk(n: integer): boolean;
var
i: integer;
begin
for i := 1 to n do
begin
if (tree[i] = 0) then continue;
if (visited[i]) then continue;
if (dfs(i) = false) then
begin
Result := false;
Exit;
end;
end;
Result := true;
end;
begin
Readln(m);
for i := 1 to m do
begin
Readln(n);
k := 0;
for j := 1 to n do
begin
Read(tree[j]);
if (tree[j] = 0) then
begin
Inc(k);
end;
end;
if (k <> 1) then
begin
Writeln('NO');
end
else
if (chk(n)) then
begin
Writeln('YES');
end
else
begin
Writeln('NO');
end;
Readln;
end;
//Readln;
end.