Problem:


Score : 500 points

Problem Statement

N players will participate in a tennis tournament. We will call them Player 1, Player 2, \ldots, Player N.

The tournament is round-robin format, and there will be N(N-1)/2 matches in total.
Is it possible to schedule these matches so that all of the following conditions are satisfied? If the answer is yes, also find the minimum number of days required.

Each player plays at most one matches in a day.

Each player i (1 \leq i \leq N) plays one match against Player A_{i, 1}, A_{i, 2}, \ldots, A_{i, N-1} in this order.

Constraints

3 \leq N \leq 1000

1 \leq A_{i, j} \leq N

A_{i, j} \neq i

A_{i, 1}, A_{i, 2}, \ldots, A_{i, N-1} are all different.

Input

Input is given from Standard Input in the following format:

N
A_{1, 1} A_{1, 2} \ldots A_{1, N-1}
A_{2, 1} A_{2, 2} \ldots A_{2, N-1}
:
A_{N, 1} A_{N, 2} \ldots A_{N, N-1}

Output

If it is possible to schedule all the matches so that all of the conditions are satisfied, print the minimum number of days required; if it is impossible, print -1.

Sample Input 1

3
2 3
1 3
1 2

Sample Output 1

3

All the conditions can be satisfied if the matches are scheduled for three days as follows:

Day 1: Player 1 vs Player 2

Day 2: Player 1 vs Player 3

Day 3: Player 2 vs Player 3

This is the minimum number of days required.

Sample Input 2

4
2 3 4
1 3 4
4 1 2
3 1 2

Sample Output 2

4

All the conditions can be satisfied if the matches are scheduled for four days as follows:

Day 1: Player 1 vs Player 2, Player 3 vs Player 4

Day 2: Player 1 vs Player 3

Day 3: Player 1 vs Player 4, Player 2 vs Player 3

Day 4: Player 2 vs Player 4

This is the minimum number of days required.

Sample Input 3

3
2 3
3 1
1 2

Sample Output 3

-1

Any scheduling of the matches violates some condition.



Sample input:
3
2 3
1 3
1 2


Sample output:
3

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
#ABC139 E

import sys
import math
import bisect
import time
sys.setrecursionlimit(1000000000)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

n = I()
a = [LI() + [-1] for _ in range(n)]
cnt,day = [0]*n,[0]*n
que = deque([i for i in range(n)])
while que:
    u = que.popleft()
    v = a[u][cnt[u]] - 1
    if a[v][cnt[v]] - 1 == u:
        day[u] = max(day[u],day[v]) + 1
        day[v] = day[u]
        cnt[u] += 1
        cnt[v] += 1
        que.append(u)
        que.append(v)
for i in range(n):
    if cnt[i] != n-1:
        print(-1)
        quit()
print(max(day))

Submission status: Accepted

Solution code:
from heapq import heappush, heappop
from collections import deque,defaultdict,Counter
import itertools
from itertools import permutations
import sys
import bisect
import string
import math
import time
ts=time.time()
sys.setrecursionlimit(10**6)
def SI():
    return input().split()
def MI():
    return map(int,input().split())
def I():
    return int(input())
def LI():
    return [int(i) for i in input().split()]
YN=['Yes','No']
mo=10**9+7

n=I()
t=[]
nx=[-1]*n
for i in range(n):
    a=[i-1 for i in LI()[::-1]]
    nx[i]=a.pop()
    t.append(a)

IsMatch=True
ans=0
MacthNum=0
search=set(range(n))

while IsMatch and MacthNum<n*(n-1)//2:
    ans+=1
    IsMatch=False
    done=set()
    nx_search=[]
    for i in search:
        if (i in done) or (nx[i] in done) or nx[i]==-1:
            continue
        c1=i
        c2=nx[i]
        if c1==nx[c2]:
            IsMatch=True
            MacthNum+=1
            if t[c1]:
                n_i=t[c1].pop()
                nx_search.append(c1)
            else:
                n_i=-1
            if t[c2]:
                n_n_i=t[c2].pop()
                nx_search.append(c2)
            else:
                n_n_i=-1
            nx[nx[i]],nx[i]=n_n_i,n_i
            done.add(c1)
            done.add(c2)
    search=[i for i in nx_search]
    ans=ans if IsMatch else -1

print(ans)

Submission status: Accepted

Solution code:
from collections import deque

n = int(input())
orders = [deque([x - 1 for x in list(map(int, input().split()))] + [-1]) for _ in range(n)]

nxt = [orders[i].popleft() for i in range(n)]
days = [0 for _ in range(n)]

q = deque([i for i in range(n)])
while q:
	a = q.popleft()
	b = nxt[a]
	if nxt[nxt[a]] == a:
		days[a], days[b] = [max(days[a], days[b]) + 1 for _ in range(2)]
		nxt[a] = orders[a].popleft()
		nxt[b] = orders[b].popleft()
		q.append(a)
		q.append(b)

if sum(nxt) == -n:
	print(max(days))
else:
	print(-1)

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)

N = int(input())
A = [[n-1 for n in list(map(int, input().split()))] + [-1] for _ in range(N)]
A = [a[::-1] for a in A]

def main(N, A):
    now = [A[i].pop() for i in range(N)]
    day = 0
    rest = N * (N-1)
    candidate = set(range(N))

    # WCS O(N**2) <- 1日に1試合だけのときN(N-1)/2回while文が繰り返される
    while True:
        # terminal condition
        # O(1)
        if rest == 0:
            return day

        change = []
        next_candidate = set()
        for i in candidate:
            if now[now[i]] == i:
                j = A[i].pop()
                change.append((i, j))
                # あとで(a, b)でnow[a] = bに更新する
                next_candidate.add(i)
                if j != -1:
                    next_candidate.add(j)
                
                rest -= 1
                have_match = True

        if len(change) == 0:
            return -1
        for (a, b) in change:
            now[a] = b
            
        candidate = next_candidate
        
        day += 1

print(main(N, A))

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)

N = int(input())
A = [[n-1 for n in list(map(int, input().split()))] + [-1] for _ in range(N)]
A = [a[::-1] for a in A]

def main(N, A):
    now = [A[i].pop() for i in range(N)]
    day = 0
    rest = N * (N-1)
    candidate = set(range(N))

    # WCS O(N**2) <- 1日に1試合だけのときN(N-1)/2回while文が繰り返される
    while True:
        # terminal condition
        # O(1)
        if rest == 0:
            return day

        # see if we have match today
        # O(N)
        have_match = False
        # tmp = now.copy()
        # for i in range(N):
        #     if now[now[i]] == i:
        #         tmp[i] = A[i].pop()
        #         rest -= 1
        #         have_match = True
        # now = tmp
        change = []
        next_candidate = set()
        for i in candidate:
            if now[now[i]] == i:
                j = A[i].pop()
                change.append((i, j))
                # あとで(a, b)でnow[a] = bに更新する
                next_candidate.add(i)
                if j != -1:
                    next_candidate.add(j)
                
                rest -= 1
                have_match = True

        if len(change) == 0:
            return -1
        for (a, b) in change:
            now[a] = b
            
        candidate = next_candidate
        
        day += 1

print(main(N, A))

Submission status: Accepted

Solution code:
from heapq import heappush, heappop
from collections import deque,defaultdict,Counter
import itertools
from itertools import permutations
import sys
import bisect
import string
import math
import time
ts=time.time()
sys.setrecursionlimit(10**6)
def SI():
    return input().split()
def MI():
    return map(int,input().split())
def I():
    return int(input())
def LI():
    return [int(i) for i in input().split()]
YN=['Yes','No']
mo=10**9+7

n=I()
t=[]
d=[]
nx=[0]*n
for i in range(n):
    a=[i-1 for i in LI()[::-1]]
    nx[i]=a.pop()
    t.append(a)
    d.append([-1]*(n))

flg=True
ans=0
MacthNum=0
yet=set(range(n))
n_yet=set(range(n))
while flg and MacthNum<n*(n-1)//2:
    elp=time.time()-ts
    if elp>1.8:
        ans=0#n*(n-1)//2
        break
    ans+=1
    IsMatch=False
    done=set()
    n_yet=[]
    #print('Day',ans,IsMatch,nx)
    for i in yet:
        if (i in done) or (nx[i] in done) or nx[i]==n:
            continue
        c1=i
        c2=nx[i]
        if c1==nx[c2]:
            IsMatch=True
            MacthNum+=1
            #print('Day',ans,'Match',c1,'vs',c2)
            if t[c1]:
                n_i=t[c1].pop()
                n_yet.append(c1)
            else:
                n_i=n
            if t[c2]:
                n_n_i=t[c2].pop()
                n_yet.append(c2)
            else:
                n_n_i=n
            #print(i,nx[i],nx)
            nx[nx[i]],nx[i]=n_n_i,n_i
            done.add(c1)
            done.add(c2)
            #print('i,t,d',i,t,'done=',done,'nx=',nx,n_i,n_n_i)
    yet=[i for i in n_yet]
    ans=ans if IsMatch else -1
    flg=True if IsMatch else False

print(ans)

Submission status: Accepted

Solution code:
# YouTube1

def main():
    n = int(input())
    a = [list(map(lambda x: int(x) - 1, input().split()))[::-1] for _ in range(n)]
    #    print(a)
    gam = []  # １日のgames
    # 初期化
    for i in range(n):
        ii = a[i][-1]
        if ii < i: continue
        if a[ii][-1] == i:
            gam.append([i, ii])
    days = 0
    fin = [False] * n
    fin_cnt = 0
    #    print(gam)
    while 1:
        days += 1
        pla = []  # 今日試合があったplayers
        for i, ii in gam:
            a[i].pop()
            a[ii].pop()
            pla.append(i)
            pla.append(ii)
        gam = []
        dec = set()
        for i in pla:
            if fin[i]: continue
            if not a[i]:
                fin[i] = True
                fin_cnt += 1
                if fin_cnt == n:
                    print(days)
                    exit()
                continue
            if i in dec: continue
            ii = a[i][-1]
            if a[ii][-1] == i:
                gam.append([i, ii])
                dec.add(ii)
        if not gam:
            print(-1)
            exit()

main()

Submission status: Accepted

Solution code:

import sys
N = int(input())
A = [[0] * (N-1)]+[list(map(int,input().split())) for _ in range(N)]

idx = [0] * (N+1)
cnt = 0
day = 0
flag_max = [False] * (N+1)
looplist = list(range(1,N+1))
while cnt != N:
    
    error = True
    flag =[False] * (N+1)
    nxtlst = []
    
    while looplist:
        
        i = looplist.pop()
        if (flag[i]) or flag_max[i]:continue
        tmp = A[i][idx[i]]
        if (flag[tmp]) or flag_max[tmp]:continue
    
        if A[tmp][idx[tmp]] == i:
            nxtlst.append(i)
            nxtlst.append(tmp)
            idx[tmp] = idx[tmp] + 1
            idx[i] = idx[i] + 1
            if idx[tmp] == N-1:
                flag_max[tmp] = True
                cnt += 1
            if idx[i] == N-1:
                flag_max[i] = True
                cnt += 1
            flag[i] = True
            flag[tmp] = True
            error = False
    looplist = nxtlst
    if error:
        print(-1)
        sys.exit()
    
    day += 1
            

    if day > 10000:
        print(N*(N-1)//2)
        sys.exit()
    
    
print(day)

Submission status: Accepted

Solution code:
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(lambda x:x-1, list(map(int, input().split()))))for i in range(n)]


    # 試合を頂点とする(ex 1-2,2-4 : i < j)
    v = 0  # 頂点数
    # 頂点にIDをふる
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:
                Id[i][j] = v
                Id[j][i] = v
                v += 1

    # 頂点間の辺を貼る
    e = [[] for i in range(maxv)]
    for i in range(n):
        # a[i][j]にIDを代入する Id[1][3]=1 => a[1][3] = a[3][1] = 1
        for j in range(n - 1):
            a[i][j] = Id[i][a[i][j]]

        # 辺をはる
        for j in range(n - 2):
            e[a[i][j]].append(a[i][j+1])


    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]
    def dfs(v):
        if dp[v] != -1:
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True #帰りがけ
        return dp[v]
    

    #トポロジカルソート
    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  # サイクル検知
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def MAP(): return list(map(int,input().split()))
import collections

n = int(input())
a = [MAP() for _ in range(n)]
q = list(range(n))
c = collections.defaultdict(int)
t = [0]*n
r=0

while q:
    r += 1
    nq = []
    for i in q:
        j = a[i][t[i]]-1
        k = i
        if k<j:
            j,k = k,j
        c[(j,k)] += 1
        if c[(j,k)] == 2:
            t[j] += 1
            t[k] += 1
            if t[j] < n-1:
                nq.append(j)
            if t[k] < n-1:
                nq.append(k)
    q = nq

for tt in t:
    if tt!=n-1:
        print(-1)
        exit(0)
print(r)

Submission status: Accepted

Solution code:
import sys
import time
def input():
    return sys.stdin.readline()
 
def main():
    a = time.time()
    N = int(input())
    A = [list(map(int, input().split())) for _ in range(N)]
    l = [0] * N
    ans = 0
    count = 0
    check = [False] * N
    tmpl = []
    next = False
 
    while(count < N):
        check = [False] * N
        for i in range(N):
            if l[i] < N - 1:
                to = A[i][l[i]] - 1
                if (not check[to]) and (not check[i]):
                    if A[to][l[to]] - 1 == i:
                        l[i] += 1
                        l[to] += 1
                        check[to] = True
                        check[i] = True
                        next = True
                    if l[i] == N - 1:
                        count += 1
                    if l[to] == N - 1:
                        count += 1
        ans += 1
        if not next:
            print(-1)
            exit()
        next = False

        b = time.time()
        if b - a >= 1.7:
            print(N*(N - 1)//2)
            exit()
        # print(l, ans)
 
    print(ans)
 
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
from collections import deque
import copy, sys

input = sys.stdin.readline
n = int(input())
a = [deque(map(lambda x: int(x) - 1, input().split())) for _ in range(n)]
q = deque()
pre_q = deque()
day = 0

def check(p, q):
    if not len(a[p]):
        return
    o = a[p][0]
    if p == a[o][0]:
        if p > o: p, o = o, p
        if not (p, o) in q:
            q.append((p, o))

fin = []
for p in range(n):
    if not p in fin:
        o = a[p][0]
        if p == a[o][0]:
            q.append((p, o))
            fin += [p, o]

while q:
    day += 1
    pre_q = copy.copy(q)
    q.clear()
    for (p, o) in pre_q:
        a[p].popleft()
        a[o].popleft()
        check(p, q)
        check(o, q)

if all(map(len, a)):
    print(-1)
else:
    print(day)

Submission status: Accepted

Solution code:
import sys
from collections import deque

n = int(input())
a = [deque(map(int, sys.stdin.readline().rstrip().split())) for _ in range(n)]

current = []

for i in range(n):
    target = a[i][0] -1
    if a[target][0] -1 == i and i < target:
        current.append([i, target])

day = 0
zc = 0
while True:
    popped = 0
    plist = set()
    zeros = 0
    tc = []
    for i in current:
        a[i[0]].popleft()
        a[i[1]].popleft()
        if len(a[i[0]]) > 0:
            plist.add(i[0])
        else:
            zc += 1
        if len(a[i[1]]) > 0:
            plist.add(i[1])
        else:
            zc += 1
    for i in plist:
        target = a[i][0] -1
        if a[target][0] -1 == i:
            if not target in plist or i < target:
                tc.append([i, target])
    day += 1
    if len(tc) == 0:
        break
    current = tc

if zc != n:
    day = -1

print(day)

Submission status: Accepted

Solution code:
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(int, input().split())) for i in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1

    # 試合を頂点とする(ex 1-2,2-4 : i < j)
    v = 0  # 頂点数
    # 頂点にIDをふる
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:
                Id[i][j] = v
                Id[j][i] = v
                v += 1


    # 頂点間の辺を貼る
    e = [[] for i in range(maxv)]
    for i in range(n):
        # a[i][j]にIDを代入する Id[1][3]=1 => a[1][3] = a[3][1] = 1
        for j in range(n - 1):
            a[i][j] = Id[i][a[i][j]]

        # 逆向きに辺をはる
        for j in range(n - 2):
            e[a[i][j]].append(a[i][j+1])



    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]

    def dfs(v):
        if dp[v] != -1:  # サイクル検知
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  # サイクル検知
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline #高速化期待
from collections import deque

def main():
    N = int(input())
    A = [deque()] + [deque( map( int, input().split())) for _ in range(N)]
    NOW = [0]*(N+1)
    Days = [0]*(N+1)
    q = deque( [ i+1 for i in range(N)])
    while q:
      i = q.popleft()
      if not A[i]:
        continue
      
      a = A[i].popleft()
      
      if NOW[a] == i:
        NOW[a] = 0
        Days[a] = Days[i] = max((Days[i], Days[a])) + 1
        q.append(i)
        q.append(a)
      else:
        NOW[i] = a
    for i in range(N+1):
      if A[i]:
        print(-1)
        return
    print(max(Days))
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.readline
    
    N = int(input())
    A = []
    tmp = (0,)*(N+1)
    A.append(tmp)
    for i in range(N):
        tmp = (0,) + tuple(map(int, input().split()))
        A.append(tmp)
    B = [1]*(N+1)
    C = [[0]*N for i in range(N+1)]
    count = 0
    flag = 0
    
    #1試合目
    Q = []
    nextQ = []
    for i in range(1,N+1):
        j = A[i][B[i]]
        if A[j][B[j]] == i:
            ii = min(i,j)
            jj = max(i,j)
            if not (ii,jj) in nextQ:
                nextQ.append((ii,jj))
    
    day = 0    
    while count < N*(N-1)//2 and len(nextQ) >= 1:
        day += 1
        Q = nextQ
        nextQ = []
        for T in Q:
            i = T[0]
            j = T[1]
            k = max(C[i][B[i]-1], C[j][B[j]-1]) + 1
            C[i][B[i]] = k
            C[j][B[j]] = k
            B[i] += 1
            B[j] += 1
            count += 1
            if B[i] < N:
                I = A[i][B[i]]
                if A[I][B[I]] == i:
                    ii = min(i,I)
                    jj = max(i,I)
                    if not (ii,jj) in nextQ:
                        nextQ.append((ii,jj))
            if B[j] < N:
                J = A[j][B[j]]
                if A[J][B[J]] == j:
                    ii = min(j,J)
                    jj = max(j,J)
                    if not (ii,jj) in nextQ:
                        nextQ.append((ii,jj))
            
                    
    #print(C)
    if count < N*(N-1)//2:
        print(-1)
    else:
        print(day)
    
    
    
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(int, input().split())) for i in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1

    # 試合を頂点とする(ex 1-2,2-4 : i < j)
    v = 0  # 頂点数
    # 頂点にIDをふる
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:  # 3-1はダメ
                Id[i][j] = v
                Id[j][i] = v
                v += 1


    e = [[] for i in range(maxv)]
    for i in range(n):
        for j in range(n - 1):
            # a[i][j]にIDを代入する Id[1][3]=1 => a[1][3] = a[3][1] = 1
            # x = i
            # y = a[i][j]
            # if x > y:
            #     x, y = y, x
            # a[i][j] = Id[x][y]  # toId(i, a[i][j])
            a[i][j] = Id[i][a[i][j]]
        for j in range(n - 2):
            e[a[i][j + 1]].append(a[i][j])


    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]

    def dfs(v):
        if dp[v] != -1:  # サイクル検知
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  # detected cycle
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import math
import collections
import heapq
from collections import defaultdict
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    n = int(input())
    maxv = n*(n-1)//2
    a = [list(map(int, input().split())) for i in range(n)]
    for i in range(n):
        for j in range(n-1):
            a[i][j] -= 1

    v = 0  # 頂点数
    # 頂点にIDをふる
    Id = [[-1 for i in range(n)] for j in range(n)]
    for i in range(n):
        for j in range(n):
            if i < j:  # 1-3 ,2-4など　3-1はダメ
                Id[i][j] = v
                v += 1

    def toId(i, j):
        if i > j:
            i, j = j, i
        return Id[i][j]



    e = [[] for i in range(maxv)]
    for i in range(n):
        for j in range(n - 1):
            # a[i][j]にIDを代入する Id[1][3]=1 => a[1][3] = a[3][1] = 1
            x = i
            y = a[i][j]
            if x > y:
                x, y = y, x
            a[i][j] = Id[x][y]  # toId(i, a[i][j])
        for j in range(n - 2):
            e[a[i][j + 1]].append(a[i][j])


    calculated = [False for i in range(maxv)]
    dp = [-1 for i in range(maxv)]

    def dfs(v):
        if dp[v] != -1:  # サイクル検知
            if not calculated[v]:
                return -1
            return dp[v]
        dp[v] = 1
        for u in e[v]:
            ret = dfs(u)
            if ret == -1:
                return -1
            dp[v] = max(dp[v], ret + 1)
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(v):
        ret = dfs(i)
        if ret == -1:  # detected cycle
            print(-1)
            exit()
        ans = max(ans, ret)
    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
#ABC139 E

import sys
import math
import bisect
import time
sys.setrecursionlimit(1000000000)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

n = I()
a = [deque() for _ in range(n)]
for i in range(1,n+1):
    x = LI()
    for j in x:
        a[i-1].append((i,j))
ans = 0
s = time.time()
for j in range(n*(n-1)//2+1):
    check = [1]*n
    flg = False
    flg2 = False
    if time.time() - s > 1.6:
        print(n*(n-1)//2)
        quit()
    for i in range(n):
        if len(a[i]) == 0 or check[i] == 0:
            continue
        (x,y) = a[i].popleft()
        flg2 = True
        check[i] = 0
        if a[y-1][0] == (y,x) and check[y-1]:
            a[y-1].popleft()
            flg = True
            check[y-1] = 0
        else:
            a[i].appendleft((x,y))
    if flg:
        ans += 1
    if not flg:
        for i in a:
            if len(i) != 0:
                print(-1)
                quit()
    if not flg2:
        print(ans)
        quit()

Submission status: Accepted

Solution code:
n = int(input())
a = []
for _ in range(n+1):
    a.append([-1])
for i in range(n):
    inp = list(map(int, input().split()))
    for j in range(n-2, -1, -1):
        a[i+1].append(inp[j])
matched = [i for i in range(1, n+1)]
finish = 0
days = 0
while True:
    used = set()
    while matched != []:
        i = matched.pop()
        p = a[i][-1]
        if p != -1 and a[p][-1] == i and (i not in used) and (p not in used) :
            a[i].pop()
            a[p].pop()
            used.add(i)
            used.add(p)
            if a[i][-1] == -1:
                finish += 1
            if a[p][-1] == -1:
                finish += 1
    days += 1
    matched = list(used)
    if len(used) == 0:
        days = -1
        break
    elif finish == n:
        break
print(days)

Submission status: Accepted

Solution code:

N = int(input())

A = []

for i in range(N):

    a = list(map(int,input().split()))

    A.append(a)

Q = []
for i in range(N):

    if A[ A[i][0]-1 ][0] == i + 1 and A[i][0]-1 > i:
        Q.append([min(A[i][0]-1,i),max(A[i][0]-1,i),1])

day = 0

while len(Q) > 0:

    q = Q.pop(0)

    del A[q[0]][0]
    del A[q[1]][0]




    if len(A[q[0]]) > 0 and A[ A[q[0]][0] - 1 ][0] == q[0] + 1:
        Q.append([min(A[q[0]][0] - 1,q[0]),max(A[q[0]][0] - 1,q[0]),q[2]+1])

    if len(A[q[1]]) > 0 and A[ A[q[1]][0] - 1 ][0] == q[1] + 1:
        Q.append([min(A[q[1]][0] - 1,q[1]),max(A[q[1]][0] - 1,q[1]),q[2]+1])

    day = max(day,q[2])

flag = True

for a in A:
    if len(a) > 0:
        flag = False
        
if flag:
    print (day)
else:
    print (-1)

Submission status: Accepted

Solution code:
def main():
    N = int(input())
    a = [list(map(int, input().split())) for i in range(N)]
    
    now = [0] * N
    day = 0
    gamed_day = [-1] * N
    
    ind = [i for i in range(N)]

    while len(ind) > 0:
        next_ = []
        while len(ind) > 0:
            i = ind.pop(-1)
            if now[i] < N-1 and gamed_day[i] != day:
                all_finish = False
                want = a[i][now[i]] - 1
                if gamed_day[want] != day:# 今日試合していない
                    if a[want][now[want]] - 1 == i:# 相手の試合相手が自分
                        now[want] += 1
                        now[i] += 1
                        if now[want] < N-1:
                            next_.append(want)
                        if now[i] < N-1:
                            next_.append(i)
                        gamed_day[i] = day
                        gamed_day[want] = day
                        had_game = True
                        # print(day+1, i+1, want+1)
        ind = next_
        day += 1
    ok = True
    for i in range(N):
        if now[i] < N-1:
            ok = False
            break
    if ok:
        print(day)
    else:
        print(-1)


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
from collections import deque

N = int(input())
A = [list(reversed(list(map(lambda x: int(x) - 1, input().split())))) for _ in range(N)]
B = {i: row for i, row in enumerate(A)}

# print (A)
# print (B)

end = 0

for k in range(8000):
    used = set()
    dels = []
    for i, q in B.items():
        if not q:
            continue
        if i in used:
            continue
        j = q[-1]
        if j in used:
            continue
        if A[j][-1] == i:
            A[j].pop()
            A[i].pop()
            used.add(i)
            used.add(j)
            if not A[i]:
                end += 1
                dels.append(i)
            if not A[j]:
                end += 1
                dels.append(j)
    if not used:
        print (-1)
        exit()
    
    if end == N:
        print (k + 1)
        exit()
    
    for i in dels:
        del B[i]
        
print (N * (N - 1) // 2)

Submission status: Accepted

Solution code:
from heapq import heappush, heappop
from collections import deque,defaultdict,Counter
import itertools
from itertools import permutations
import sys
import bisect
import string
import math
import time
ts=time.time()
sys.setrecursionlimit(10**6)
def SI():
    return input().split()
def MI():
    return map(int,input().split())
def I():
    return int(input())
def LI():
    return [int(i) for i in input().split()]
YN=['Yes','No']
mo=10**9+7

n=I()
t=[]
d=[]
nx=[0]*n
for i in range(n):
    a=[i-1 for i in LI()[::-1]]
    nx[i]=a.pop()
    t.append(a)
    d.append([-1]*(n))

flg=True
ans=0
MacthNum=0
yet=set(range(n))
n_yet=set(range(n))
while flg and MacthNum<n*(n-1)//2:
    elp=time.time()-ts
    if elp>1.8:
        ans=n*(n-1)//2
        break
    ans+=1
    IsMatch=False
    done=set()
    for i in yet:
        if (i in done) or (nx[i] in done) or nx[i]==n:
            continue
        c1=i
        c2=nx[i]
        if c1==nx[c2]:
            IsMatch=True
            MacthNum+=1
            if t[c1]:
                n_i=t[c1].pop()
            else:
                n_i=n
                n_yet.remove(c1)
            if t[c2]:
                n_n_i=t[c2].pop()
            else:
                n_n_i=n
                n_yet.remove(c2)
            nx[nx[i]],nx[i]=n_n_i,n_i
            done.add(c1)
            done.add(c2)
    yet=[i for i in n_yet]
    ans=ans if IsMatch else -1
    flg=True if IsMatch else False

print(ans)