結果
| 問題 | No.1865 Make Cycle |
| コンテスト | |
| ユーザー |
norioc
|
| 提出日時 | 2026-08-23 16:30:40 |
| 言語 | PyPy3 (7.3.23) |
| 結果 |
AC
|
| 実行時間 | 1,047 ms / 3,000 ms |
| + 550µs | |
| コード長 | 2,552 bytes |
| 記録 | |
| コンパイル時間 | 261 ms |
| コンパイル使用メモリ | 95,984 KB |
| 実行使用メモリ | 290,956 KB |
| 最終ジャッジ日時 | 2026-08-23 16:30:58 |
| 合計ジャッジ時間 | 17,379 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge1_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 20 |
ソースコード
from collections import defaultdict
from enum import Enum, auto
import sys
sys.setrecursionlimit(10**6)
class E(Enum):
NOT_FOUND = auto() # 閉路は見つからなかった
BUILDING = auto() # 閉路を構築中
COMPLETED = auto() # 閉路を構築済み
def detect_directed_cycle(n: int, adj):
"""
有向グラフの閉路を求める
n: 頂点数
adj: 隣接頂点 {v: [隣接頂点, ...]}
return:
(閉路が存在するか, 閉路の頂点パス)
"""
def dfs(v, dists, used): # -> tuple[E, int, tuple[int, int | None] | None]:
"""
return:
(state, cycle_start, path)
state: E
cycle_start: 閉路の始点
path: 閉路の頂点パス
"""
for to in adj[v]:
if used[to]: continue
nd = dists[v] + 1
if dists[to] < nd: # 閉路が見つかった
return E.BUILDING, to, (v, None)
elif dists[to] == INF:
dists[to] = nd
state, cycle_start, path = dfs(to, dists, used)
used[to] = True # 帰りがけ
if state == E.COMPLETED:
return state, cycle_start, path
elif state == E.BUILDING:
if v == cycle_start:
return E.COMPLETED, cycle_start, (v, path)
else:
return state, cycle_start, (v, path)
return E.NOT_FOUND, -1, None
dists = [INF] * n
used = [False] * n
for i in range(n):
if used[i]: continue
dists[i] = 0
state, _, path = dfs(i, dists, used)
used[i] = True # 帰りがけ
if state == E.COMPLETED:
p = path
return True, None
return False, None
def bsearch_right(low: int, high: int, pred) -> int:
assert pred(high)
lo = low
hi = high
res = high
while lo <= hi:
m = (lo + hi) // 2
if pred(m):
res = min(res, m)
hi = m - 1
else:
lo = m + 1
return res
def can(m: int) -> bool:
adj = defaultdict(list)
for i in range(m):
u, v = edges[i]
adj[u].append(v)
found, _ = detect_directed_cycle(N, adj)
return found
INF = 1 << 62
N, Q = map(int, input().split())
edges = []
for _ in range(Q):
A, B = map(lambda x: int(x)-1, input().split())
edges.append((A, B))
if not can(Q):
print(-1)
exit()
res = bsearch_right(1, Q, can)
print(res)
norioc