結果
| 問題 |
No.2263 Perms
|
| コンテスト | |
| ユーザー |
👑 Kazun
|
| 提出日時 | 2023-04-07 22:33:06 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 102 ms / 2,000 ms |
| コード長 | 2,562 bytes |
| コンパイル時間 | 156 ms |
| コンパイル使用メモリ | 82,044 KB |
| 実行使用メモリ | 77,136 KB |
| 最終ジャッジ日時 | 2024-10-02 19:59:10 |
| 合計ジャッジ時間 | 4,270 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 39 |
ソースコード
# 参考 URL
# https://snuke.hatenablog.com/entry/2019/05/07/013609
class Bipartite_Matching:
def __init__(self,M,N):
""" サイズが M,N からなる二部空グラフを作成する.
"""
self.M=M; self.N=N
self.edge=[[] for _ in range(M)]
def add_edge(self, a, b):
""" 辺 Aa Bb を加える.
"""
assert 0<=a<self.M and 0<=b<self.N
self.edge[a].append(b)
def max_matching(self, mode):
M=self.M; N=self.N; edge=self.edge
pre=[-1]*M; root=[-1]*M
p=[-1]*M; q=[-1]*N
upd=True
size=0
while upd:
upd=False
S=[]
Index=0
for i in range(M):
if p[i]==-1:
root[i]=i
S.append(i)
while Index<len(S):
v=S[Index]
Index+=1
if p[root[v]]!=-1:
continue
for u in edge[v]:
if q[u]==-1:
while u!=-1:
q[u]=v
p[v],u=u,p[v]
v=pre[v]
upd=True
size+=1
break
u=q[u]
if pre[u]!=-1:
continue
pre[u]=v
root[u]=root[v]
S.append(u)
if upd:
pre=[-1]*M
root=[-1]*M
if mode==0:
return size
else:
A=[-1]*M; B=[-1]*N
for i in range(M):
if p[i]!=-1:
A[i]=p[i]
B[p[i]]=i
return size,(A,B)
#==================================================
def solve():
N,M=map(int,input().split())
A=[None]*N
S=[0]*N
for i in range(N):
A[i]=list(map(int,input().split()))
if sum(A[i])!=M:
print(-1)
return
for j in range(N):
S[j]+=A[i][j]
if not all(S[j]==M for j in range(N)):
print(-1)
return
for _ in range(M):
G=Bipartite_Matching(N,N)
for i in range(N):
for j in range(N):
if A[i][j]>=1:
G.add_edge(i,j)
_,(P,_)=G.max_matching(True)
for i in range(N):
A[i][P[i]]-=1
print(*[P[i]+1 for i in range(N)])
return
#==================================================
solve()
Kazun