結果

問題 No.1976 Cut then Connect
ユーザー lilictakalilictaka
提出日時 2022-09-29 22:15:43
言語 PyPy3
(7.3.15)
結果
WA  
実行時間 -
コード長 4,287 bytes
コンパイル時間 192 ms
コンパイル使用メモリ 82,032 KB
実行使用メモリ 132,432 KB
最終ジャッジ日時 2024-06-02 02:13:44
合計ジャッジ時間 13,290 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 39 ms
56,508 KB
testcase_01 AC 40 ms
56,576 KB
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 AC 39 ms
55,832 KB
testcase_24 AC 41 ms
56,168 KB
testcase_25 AC 40 ms
56,004 KB
testcase_26 AC 38 ms
56,064 KB
testcase_27 WA -
testcase_28 AC 38 ms
56,164 KB
testcase_29 AC 37 ms
55,972 KB
testcase_30 WA -
testcase_31 AC 38 ms
56,796 KB
testcase_32 AC 37 ms
55,904 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

from itertools import combinations
from heapq import heappop,heappush
from collections import deque
class Const_Tree():
    def __init__(self,N) -> None:
        self.const_edge = [[] for _ in range(N)]
        self.parent = [-1 for _ in range(N)]
        self.rev_edge = [[] for _ in range(N)]
        self.q = deque()
        self.edge = [[] for _ in range(N)]
        self.N = N
    def add_edge(self,u,v):
        self.edge[u].append(v)
    def const(self,st):
        self.q.append(st)
        seen = [False for _ in range(self.N)]
        while self.q:
            now = self.q.popleft()
            seen[now] = True
            for next in self.edge[now]:
                if not seen[next]:
                    self.q.append(next)
                    self.const_edge[now].append(next)
                    self.parent[next] = now
                    self.rev_edge[next].append(now)
        self.q = deque()
        self.parts = [1 for _ in range(self.N)]#部分木の数
        for i in range(self.N):
            if len(self.const_edge[i]) == 0:
                self.q.append(i)
        self.cnt = [0 for _ in range(self.N)]
        while self.q:
            now = self.q.popleft()
            for next in self.rev_edge[now]:
                self.parts[next] += self.parts[now]
                self.cnt[next] += 1
                if self.cnt[next] == len(self.const_edge[next]):
                    self.q.append(next)
def topological_sort(G):
    ret = []
    start = []
    par_count = [0] * len(G)
    for u in range(len(G)):
        for v in G[u]:
            par_count[v] += 1
    for v in range(len(G)):
        if par_count[v] == 0:
            start.append(v)

    while start:
        u = start.pop()
        ret.append(u)
        for v in G[u]:
            par_count[v] -= 1
            if par_count[v] == 0:
                start.append(v)

    if any(c > 0 for c in par_count):
        # G is not a DAG
        return None
    return ret

N = int(input())
ct = Const_Tree(N)
for _ in range(N-1):
    u,v = map(int,input().split())
    u-=1
    v-=1
    ct.add_edge(u,v)
    ct.add_edge(v,u)
ct.const(0)
edge = ct.const_edge
P = ct.parent
downmemo = [[] for _ in range(N)]
down = [0] * N
up = [0] * (N)
upsub = [0] * N
tp = topological_sort(edge)
dlen = [1]  * N
def f(List,c):
    tmp = []
    while List:
        x,u = heappop(List)
        tmp.append((x,u))
    for x,u in tmp:
        heappush(List,(x,u))
    if len(List) <=1:
        return 0
    elif len(List) == 2:
        for x,u in tmp:
            if u != c:
                return -x
    elif len(List) ==3:
        for i,k in combinations([l for l in range(3)],2):
            if tmp[i][1] != c and tmp[k][1] != c:
                return -tmp[i][0] - tmp[k][0] - 1
def g(List):
    tmp = []
    while List:
        x,u = heappop(List)
        tmp.append((x,u))
    for x,u in tmp:
        heappush(List,(x,u))
    if len(List) == 0:
        return 1
    elif len(List) == 1:
        return -tmp[0][0]
    elif len(List) >=2:
        return -tmp[0][0] - tmp[1][0] -1
def m(List,c):
    tmp = []
    while List:
        x,u = heappop(List)
        tmp.append((x,u))
    for x,u in tmp:
        heappush(List,(x,u))
    if len(List) == 0:
        return 0
    if len(List) == 1:
        return 1
    else:
        for x,u in tmp:
            if u != c:
                return -tmp[0][0]


for u in tp[::-1]:
    for cu in edge[u]:
        dlen[u] = max(dlen[cu]+1,dlen[u])
        heappush(downmemo[u],(-dlen[cu]-1,cu))
        if len(downmemo[u]) > 3:
            tmp = []
            for _ in range(3):
                x,u1 = heappop(downmemo[u])
                tmp.append((x,u1))
            while downmemo[u]:
                x,u1 = heappop(downmemo[u])
            for x,u1 in tmp:
                heappush(downmemo[u],(x,u1))
    for cu in edge[u]:
        up[cu] = max(f(downmemo[u],cu),up[cu])
for u in tp:
    up[u] = max(upsub[u],up[u])
    for cu in edge[u]:
        upsub[cu] = max(m(downmemo[u],cu),upsub[cu])
        up[cu] = max(up[u],up[cu])
        upsub[cu] = max(upsub[cu],upsub[u] + 1)
ans = [0] * N
for u in range(N):
    down[u] = max(g(downmemo[u]) , down[u])
    if up[u] != 0 :
        ans[u] = (up[u]+1)//2 + (down[u] + 1)//2
    else:
        ans[u] = down[u]-1
print(min(ans))

0