結果
| 問題 | No.2642 Don't cut line! |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-02-19 22:25:04 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 648 ms / 4,000 ms |
| コード長 | 3,069 bytes |
| 記録 | |
| コンパイル時間 | 218 ms |
| コンパイル使用メモリ | 82,332 KB |
| 実行使用メモリ | 157,568 KB |
| 最終ジャッジ日時 | 2024-09-29 03:35:06 |
| 合計ジャッジ時間 | 15,870 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 33 |
ソースコード
import sys
from itertools import permutations
from heapq import heappop,heappush
from collections import deque
import random
import bisect
input = lambda :sys.stdin.readline().rstrip()
mi = lambda :map(int,input().split())
li = lambda :list(mi())
class UnionFindVerSize():
def __init__(self, N):
self._parent = [n for n in range(0, N)]
self._size = [1] * N
self.group = N
def find_root(self, x):
if self._parent[x] == x: return x
self._parent[x] = self.find_root(self._parent[x])
return self._parent[x]
def unite(self, x, y):
gx = self.find_root(x)
gy = self.find_root(y)
if gx == gy: return
self.group -= 1
if self._size[gx] < self._size[gy]:
self._parent[gx] = gy
self._size[gy] += self._size[gx]
else:
self._parent[gy] = gx
self._size[gx] += self._size[gy]
def get_size(self, x):
return self._size[self.find_root(x)]
def is_same_group(self, x, y):
return self.find_root(x) == self.find_root(y)
def solve(N,M,C,Edge):
Edge.sort(key=lambda e:e[2])
uf = UnionFindVerSize(N)
MST_edge = [[] for v in range(N)]
total_cost = 0
res = -1
rest_Edge = []
for u,v,w,p in Edge:
if not uf.is_same_group(u,v):
uf.unite(u,v)
MST_edge[u].append((v,w))
MST_edge[v].append((u,w))
total_cost += w
res = max(res,p)
else:
rest_Edge.append((u,v,w,p))
if total_cost > C:
return -1
K = 17
parent = [[(-1,-1)]*N for i in range(K)]
dep = [0] * N
deq = deque([0])
while deq:
v = deq.popleft()
for nv,w in MST_edge[v]:
if nv == parent[0][v][0]:
continue
parent[0][nv] = (v,w)
dep[nv] = dep[v] + 1
deq.append(nv)
for k in range(1,K):
for v in range(N):
pv,nw = parent[k-1][v]
if pv!=-1:
ppv,nnw = parent[k-1][pv]
parent[k][v] = (ppv,max(nnw,nw))
def maxi_w_on_path(u,v):
if dep[u] > dep[v]:
u,v = v,u
diff = dep[v] - dep[u]
res = -1
for k in range(K)[::-1]:
if diff>>k & 1:
pv,w = parent[k][v]
res = max(res,w)
v = pv
if u == v:
return res
for k in range(K)[::-1]:
pu,uw = parent[k][u]
pv,vw = parent[k][v]
if pu!=pv:
u,v = pu,pv
res = max(res,uw,vw)
pu,uw = parent[0][u]
pv,vw = parent[0][v]
return max(res,uw,vw)
for u,v,w,p in rest_Edge:
tmp_cost = total_cost - maxi_w_on_path(u,v) + w
if tmp_cost <= C:
res = max(res,p)
return res
N,M,C = mi()
Edge = []
for _ in range(M):
u,v,w,p = mi()
Edge.append((u-1,v-1,w,p))
print(solve(N,M,C,Edge))