結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
convexineq
|
| 提出日時 | 2019-11-09 20:38:26 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 3,883 bytes |
| コンパイル時間 | 329 ms |
| コンパイル使用メモリ | 82,176 KB |
| 実行使用メモリ | 193,024 KB |
| 最終ジャッジ日時 | 2024-09-15 04:51:08 |
| 合計ジャッジ時間 | 4,929 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | RE * 4 |
| other | WA * 3 RE * 23 |
ソースコード
# 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,vのLCAを返す
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): xのいる組とyのいる組をまとめる
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 #yをxにつなぐ
return True
def issame(self, x, y): #same(x,y): xとyが同じ組ならTrue
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**8)
readline = sys.stdin.readline
#n = int(input())
n,m,q = [int(i) for i in readline().split()]
assert m == 99999 or m == 99916
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,wt_total):
dist = 0
maxdiff = 0
for c in g[v]:
if c == p: continue
w,d,m = dfs(c,v,wt_total)
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
ans = 0
roots = [i for i,x in enumerate(UF.parent) if i == x]
LCA = LCA_doubling(g,roots)
"""
ans = center_of_points(g,wt,roots)
for a,b in Same:
ans += LCA.getdepth(a) + LCA.getdepth(b) - 2*LCA.getdepth(LCA.getLCA(a,b))
"""
print(ans)
convexineq