結果
| 問題 |
No.1669 パズル作成
|
| コンテスト | |
| ユーザー |
penguinman
|
| 提出日時 | 2021-04-27 23:18:48 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 833 ms / 2,000 ms |
| コード長 | 2,894 bytes |
| コンパイル時間 | 351 ms |
| コンパイル使用メモリ | 82,340 KB |
| 実行使用メモリ | 79,092 KB |
| 最終ジャッジ日時 | 2024-12-15 08:43:26 |
| 合計ジャッジ時間 | 14,835 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 29 |
ソースコード
# Reference: https://github.com/shakayami/ACL-for-python
class dsu():
n=1
parent_or_size=[-1 for i in range(n)]
def __init__(self,N):
self.n=N
self.parent_or_size=[-1 for i in range(N)]
def merge(self,a,b):
assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
assert 0<=b<self.n, "0<=b<n,b={0},n={1}".format(b,self.n)
x=self.leader(a)
y=self.leader(b)
if x==y:
return x
if (-self.parent_or_size[x]<-self.parent_or_size[y]):
x,y=y,x
self.parent_or_size[x]+=self.parent_or_size[y]
self.parent_or_size[y]=x
return x
def same(self,a,b):
assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
assert 0<=b<self.n, "0<=b<n,b={0},n={1}".format(b,self.n)
return self.leader(a)==self.leader(b)
def leader(self,a):
assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
if (self.parent_or_size[a]<0):
return a
self.parent_or_size[a]=self.leader(self.parent_or_size[a])
return self.parent_or_size[a]
def size(self,a):
assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
return -self.parent_or_size[self.leader(a)]
def groups(self):
leader_buf=[0 for i in range(self.n)]
group_size=[0 for i in range(self.n)]
for i in range(self.n):
leader_buf[i]=self.leader(i)
group_size[leader_buf[i]]+=1
result=[[] for i in range(self.n)]
for i in range(self.n):
result[leader_buf[i]].append(i)
result2=[]
for i in range(self.n):
if len(result[i])>0:
result2.append(result[i])
return result2
N, M = map(int, input().split())
tree = dsu(N)
mem = [[]for i in range(N)]
for i in range(M):
r, c = map(int, input().split())
mem[r-1].append(c-1)
for i in range(N):
for j in range(1,len(mem[i])):
tree.merge(mem[i][j], mem[i][j-1])
cnt = [0]*N
x = []
y = []
for i in range(N):
if len(mem[i]) == 0:
x.append(1)
y.append(0)
else:
cnt[tree.leader(mem[i][0])] += 1
for i in range(N):
if tree.leader(i) == i:
x.append(cnt[i])
y.append(tree.size(i))
inf = int(1e18)
ans = inf
K = len(x)
dp = [inf]*(N+1)
dp[0] = 0
for i in range(K):
for j in reversed(range(N+1)):
if j < x[i]:
break
dp[j] = min(dp[j], dp[j-x[i]]+y[i])
for i in range(N+1):
if dp[i] == inf:
continue
ans = min(ans, N*N+2*i*dp[i]-dp[i]*N-i*N-M)
for i in range(K):
x[i], y[i] = y[i], x[i]
dp = [inf]*(N+1)
dp[0] = 0
for i in range(K):
for j in reversed(range(N+1)):
if j < x[i]:
break
dp[j] = min(dp[j], dp[j-x[i]]+y[i])
for i in range(N+1):
if dp[i] == inf:
continue
ans = min(ans, N*N+2*i*dp[i]-dp[i]*N-i*N-M)
print(ans)
penguinman