結果
| 問題 |
No.2914 正閉路検出
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-07-29 19:17:40 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 912 ms / 2,000 ms |
| コード長 | 3,322 bytes |
| コンパイル時間 | 453 ms |
| コンパイル使用メモリ | 82,496 KB |
| 実行使用メモリ | 140,900 KB |
| 最終ジャッジ日時 | 2024-07-29 19:17:59 |
| 合計ジャッジ時間 | 17,630 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 55 |
ソースコード
class WeightedUnionFind:
def __init__(self, n):
self.par = [i for i in range(n+1)]
self.rank = [0] * (n+1)
# 根への距離を管理
self.weight = [0] * (n+1)
# 検索
def find(self, x):
if self.par[x] == x:
return x
else:
y = self.find(self.par[x])
# 親への重みを追加しながら根まで走査
self.weight[x] += self.weight[self.par[x]]
self.par[x] = y
return y
# 併合
def union(self, x, y, w):
rx = self.find(x)
ry = self.find(y)
# xの木の高さ < yの木の高さ
if self.rank[rx] < self.rank[ry]:
self.par[rx] = ry
self.weight[rx] = w - self.weight[x] + self.weight[y]
# xの木の高さ ≧ yの木の高さ
else:
self.par[ry] = rx
self.weight[ry] = -w - self.weight[y] + self.weight[x]
# 木の高さが同じだった場合の処理
if self.rank[rx] == self.rank[ry]:
self.rank[rx] += 1
# 同じ集合に属するか
def same(self, x, y):
return self.find(x) == self.find(y)
# xからyへのコスト
def diff(self, x, y):
return self.weight[x] - self.weight[y]
def Dijkstra(s, graph):
INF = 2 ** 63 - 1
import heapq
n = len(graph)
dist = [INF] * n
dist[s] = 0
bef = [0] * n
bef[s] = s
hq = [(0, s)]
heapq.heapify(hq)
while hq:
c, now = heapq.heappop(hq)
if c > dist[now]:
continue
for to, cost in graph[now]:
if dist[now] + cost < dist[to]:
dist[to] = cost + dist[now]
bef[to] = now
heapq.heappush(hq, (dist[to], + to))
return dist, bef
def DijkstraRest(bef, t):
now = t
ret = []
while bef[now] != now:
ret.append((bef[now], now))
now = bef[now]
ret.reverse()
return ret
import sys, time, random
from collections import deque, Counter, defaultdict
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mi = lambda: map(int, input().split())
li = lambda: list(mi())
inf = 2 ** 61 - 1
mod = 998244353
n, m = mi()
assert 1 <= n <= 10 ** 5
assert 1 <= m <= 10 ** 5
graph = [[] for _ in range(n)]
U = WeightedUnionFind(n)
EDGE = {}
cnt = 1
for _ in range(m):
u, v, w = mi()
assert u != v
assert 1 <= u <= n and 1 <= v <= n
assert 0 <= w <= 10 ** 5
u -= 1
v -= 1
if U.same(u, v) and U.diff(u, v) > w:
D, r = Dijkstra(u, graph)
rest = DijkstraRest(r, v)
ans = []
for i in range(len(rest)):
ans.append(EDGE[rest[i]])
ans.append(cnt)
print(len(ans))
print(u + 1)
print(*ans)
exit()
elif U.same(u, v) and U.diff(u, v) < w:
D, r = Dijkstra(v, graph)
rest = DijkstraRest(r, u)
ans = []
for i in range(len(rest)):
ans.append(EDGE[rest[i]])
ans.append(cnt)
print(len(ans))
print(v + 1)
print(*ans)
exit()
else:
EDGE[(u, v)] = cnt
EDGE[(v, u)] = cnt
U.union(u, v, w)
graph[u].append((v, 1))
graph[v].append((u, 1))
cnt += 1
print(-1)