結果

問題 No.922 東北きりきざむたん
ユーザー convexineq
提出日時 2019-11-09 20:08:06
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 836 ms / 2,000 ms
コード長 3,847 bytes
コンパイル時間 168 ms
コンパイル使用メモリ 82,176 KB
実行使用メモリ 221,824 KB
最終ジャッジ日時 2024-09-15 04:48:00
合計ジャッジ時間 12,879 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 26
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

# coding: utf-8
# Your code here!
class LCA_doubling:
"""
parent:
depth:
"""
def __init__(self,g,roots): #g: graph
def dfs(v,p): #p: parent of v
if p != -1: self.depth[v] = self.depth[p]+1
for c in g[v]:
if c == p: continue
self.parent[0][c] = v
dfs(c,v)
return
def doubling_make_table(N,logN,Table):
for i in range(1,logN):
for j, Tiij in enumerate(Table[i-1]):
if Tiij != -1:
Table[i][j] = Table[i-1][Tiij]
N = len(g)
self.logN = len(bin(N))-2
self.parent = [[-1]*N for _ in range(self.logN)]
self.depth = [0]*(N) #
for i in roots: dfs(i,-1) #root
doubling_make_table(N, self.logN, self.parent) #
def getLCA(self,u,v): #u,vLCA
if self.depth[u] > self.depth[v]: u,v = v,u #v
dd = self.depth[v] - self.depth[u]
for k in range(self.logN-1,-1,-1):
if (dd >> k) & 1: v = self.parent[k][v]
if u == v: return u;
for k in range(self.logN-1,-1,-1):
if self.parent[k][u] != self.parent[k][v]:
u,v = self.parent[k][u], self.parent[k][v]
return self.parent[0][u];
def getdepth(self,u): #u
return self.depth[u]
##########
class UnionFind:
def __init__(self, n):
self.parent = list(range(n)) #
self.size = [1]*n #
def root(self, x): #root(x): x
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]
x = self.parent[x]
return x
def merge(self, x, y): #merge(x,y): xy
x, y = self.root(x), self.root(y)
if x == y: return False
if self.size[x] < self.size[y]: x,y=y,x #x
self.size[x] += self.size[y] #x
self.parent[y] = x #yx
return True
def issame(self, x, y): #same(x,y): xyTrue
return self.root(x) == self.root(y)
def getsize(self,x): #size(x): x
return self.size[self.root(x)]
##############
import sys
sys.setrecursionlimit(10**6)
readline = sys.stdin.readline
#n = int(input())
n,m,q = [int(i) for i in readline().split()]
g = [[] for _ in range(n)]
UF = UnionFind(n)
for i in range(m):
a,b = [int(i)-1 for i in readline().split()]
g[a].append(b)
g[b].append(a)
UF.merge(a,b)
Same = []
wt = [0]*n
#print(ab)
from collections import Counter
sum_of_wt = Counter()
for _ in range(q):
a,b = [int(i)-1 for i in readline().split()]
if UF.issame(a,b):
Same.append((a,b))
else:
sum_of_wt[UF.root(a)] += 1
sum_of_wt[UF.root(b)] += 1
wt[a] += 1
wt[b] += 1
def center_of_points(g,wt,roots): #p: parent of v
def dfs(v,p,n):
dist = 0
maxdiff = 0
for c in g[v]:
if c == p: continue
w,d,m = dfs(c,v,n)
wt[v] += w
dist += w+d
maxdiff = max(maxdiff,m+(2*w-n))
return wt[v], dist, maxdiff
res = 0
for r in roots:
w,d,m = dfs(r,-1,sum_of_wt[r])
res += d-m
return res
roots = [i for i,x in enumerate(UF.parent) if i == x]
LCA = LCA_doubling(g,roots)
#print(roots)
ans = center_of_points(g,wt,roots)
#print(ans)
for a,b in Same:
ans += LCA.getdepth(a) + LCA.getdepth(b) - 2*LCA.getdepth(LCA.getLCA(a,b))
print(ans)
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0