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:
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline

def main():
    n = int(input())

    A = [0]*n
    for i in range(n):
        a = list(map(int, input().split()))
        a = [a_-1 for a_ in a]
        A[i] = a

    g = [[] for i in range(n*(n-1)//2)]
    id = [[[-1] for i in range(n)] for j in range(n)]

    temp = 0
    for i in range(n-1):
        for j in range(i+1, n):
            id[i][j] = temp
            id[j][i] = temp
            temp += 1

    for i in range(n):
        for j in range(n-2):
            g[id[i][A[i][j]]].append(id[i][A[i][j+1]])

    visit = [-1]*(n*(n-1)*2)
    clc = [-1]*(n*(n-1)*2)
    dp = [1]*(n*(n-1)*2)
    def dfs(v):
        if visit[v] != -1:
            if clc[v] == -1:
                return -1
            return dp[v]
        visit[v] = 0
        for u in g[v]:
            res = dfs(u)
            if res == -1:
                return -1
            dp[v] = max(dp[v], res+1)
        clc[v] = 0
        return dp[v]

    ans = 0
    for i in range(n*(n-1)//2):
        res = dfs(i)
        if res == -1:
            print(-1)
            exit()
        ans = max(ans, res)
    print(ans)

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline

from collections import deque

n = int(input())
a = [[]]
for _ in range(n):
    a.append(deque([int(x) for x in input().split()]))

day = 1
next_day = []
used_player = [set() for _ in range(n**2)]

# 1日目
for i in range(1, n + 1):
    if a[a[i][0]][0] == i and (i not in used_player[day]) and (a[i][0] not in used_player[day]):
        used_player[day].add(i)
        used_player[day].add(a[i][0])
        next_day.append(a[a[i][0]].popleft())
        next_day.append(a[i].popleft())

# print(a)
# print(next_day)
from copy import deepcopy
# 2日目以降
while next_day:
    day += 1
    u = deepcopy(next_day)
    next_day = []
    # print(u)
    # print(a)
    for i in u:
        if len(a[i]) > 0 and len(a[a[i][0]]) > 0:
            if a[a[i][0]][0] == i and (i not in used_player[day]) and (a[i][0] not in used_player[day]):
                used_player[day].add(i)
                used_player[day].add(a[i][0])
                next_day.append(a[a[i][0]].popleft()) 
                next_day.append(a[i].popleft())

for i in a:
    if len(i) != 0:
        print(-1)
        sys.exit()

print(day - 1)

Submission status: Accepted

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(10**9)
INF=10**18
def input():
    return sys.stdin.readline().rstrip()

def main():
    N=int(input())
    A=[[] for _ in range(N)]
    for i in range(N):
        A[i]=deque(list(map(lambda x: int(x)-1,input().split())))
    days=1
    c=0
    pre=[]
    tmp=[]
    for i in range(N):
        if A[i] and A[A[i][0]][0]==i:
            tmp.append(i)
            tmp.append(A[i][0])
    tmp=list(set(tmp))
    for i in tmp:
        A[i].popleft()
        c+=1
    pre=tmp
    if c<N*(N-1):
        while c<N*(N-1):
            tmp=[]
            for i in pre:
                if A[i] and A[A[i][0]][0]==i:
                    tmp.append(i)
                    tmp.append(A[i][0])
            tmp=list(set(tmp))
            for i in tmp:
                A[i].popleft()
                c+=1
            pre=tmp
            days+=1
            if days>N*(N-1)//2:
                print(-1)
                exit()
    print(days)
                
            
        
    
        
        

    

        
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]


def match2int(x, y):
    x, y = min(x, y), max(x, y)
    return (2 * n - 1 - x) * x // 2 + y - x - 1


match_sm = n * (n - 1) // 2

adj = [[] for _ in range(match_sm)]
in_deg = [0] * match_sm
for i, li in enumerate(a):
    for j, k in zip(li, li[1:]):
        j -= 1
        k -= 1
        match1 = match2int(i, j)
        match2 = match2int(i, k)
        adj[match1].append(match2)
        in_deg[match2] += 1

cnd = [i for i, e in enumerate(in_deg) if e == 0]
day = 0
while cnd:
    nxt_cnd = []
    for u in cnd:
        for v in adj[u]:
            in_deg[v] -= 1
            if in_deg[v] == 0:
                nxt_cnd.append(v)

    cnd = nxt_cnd
    day += 1

if in_deg.count(0) != match_sm:
    day = -1

print(day)

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.buffer.readline
    N = int(input())
    c = [[int(i) for i in input().split()] for j in range(N)]
    from collections import defaultdict
    edge = defaultdict(set)
    deg = defaultdict(int)
    for i, A in enumerate(c, start=1):
        for j in range(N-2):
            if i < A[j]:
                if i < A[j+1]:
                    edge[i*N+A[j]].add(i*N+A[j+1])
                    deg[i*N+A[j+1]] += 1
                else:
                    edge[i*N+A[j]].add(A[j+1]*N+i)
                    deg[A[j+1]*N+i] += 1
            else:
                if i < A[j+1]:
                    edge[A[j]*N+i].add(i*N+A[j+1])
                    deg[i*N+A[j+1]] += 1
                else:
                    edge[A[j]*N+i].add(A[j+1]*N+i)
                    deg[A[j+1]*N+i] += 1
    from collections import deque
    que = deque()
    dist = defaultdict(int)
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            # print(i, j, i*N+j)
            if deg[i*N+j] == 0:
                que.append(i*N+j)  # root
                dist[i*N+j] = 1
    while que:
        u = que.popleft()
        for v in edge[u]:
            deg[v] -= 1
            dist[v] = max(dist[v], dist[u] + 1)
            if deg[v] == 0:
                que.append(v)

    if any(deg.values()):
        # 閉路検出
        print(-1)
    else:
        print(max(dist.values()))


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
N = int(input())
A = [list(map(lambda x:int(x)-1, input().split())) for _ in range(N)]

M = N*N

def c(a,b):
    if a>b: a,b=b,a
    return a*N+b

G = [[] for _ in range(M)]
for i in range(N):
    a = A[i]
    x = i
    for j in range(N-1-1):
        y1 = a[j]
        y2 = a[j+1]
        G[c(x,y1)].append(c(x,y2))

dp = [0]*M
started = [False]*M
finished = [False]*M
for i in range(N):
    for j in range(i+1, N):
        s = c(i,j)
        if started[s]: continue
        stk = [(s, 0)]
        while stk:
            v, s = stk.pop()
            if s == 0:
                if started[v]:
                    if not finished[v]:
                        print(-1)
                        exit()
                    continue
                started[v] = True
                stk.append((v, 1))
                for to in G[v]:
                    stk.append((to, 0))
            else:
                finished[v] = True
                for to in G[v]:
                    dp[v] = max(dp[v], dp[to] + 1)

print(max(dp) + 1)

Submission status: Accepted

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

N = int(input())
A = [deque(map(lambda x: int(x)-1, input().split())) for _ in range(N)]
ans = 0
used_prev = set(range(N))
while any(A):
    used = set()
    for i in used_prev:
        if not A[i] or i in used:
            continue
        j = A[i][0]
        if j in used:
            continue
        if A[j][0] == i:
            used.add(i)
            used.add(j)
            A[i].popleft()
            A[j].popleft()
    if not used:
        ans = -1
        break
    used_prev = used
    ans += 1
print(ans)

Submission status: Accepted

Solution code:
N = int(input())
A = [list(map(lambda x:int(x)-1, input().split())) for _ in range(N)]

indices = [0] * N
def next(i):
    return A[i][indices[i]] if indices[i] < N-1 else -1

from collections import deque
q = deque()
for i in range(N):
    j = next(i)
    if i < j and next(j) == i:
        q.append((i, j))

m = N*(N-1)//2
days = 0
while q:
    days += 1
    nq = deque()
    while q:
        i, j = q.pop()
        m -= 1
        indices[i] += 1
        indices[j] += 1
        ni = next(i)
        nj = next(j)
        if ni >= 0 and next(ni) == i:
            nq.append((i, ni))
        if nj >= 0 and nj != i and next(nj) == j:
            nq.append((j, nj))
    q = nq

if m > 0:
    print(-1)
else:
    print(days)

Submission status: Accepted

Solution code:
from collections import deque

def main():
    n = int(input())
    a = []
    for i in range(n):
        a.append(list(map(int, input().split())))

    que = deque()
    lastdone = []
    next = []
    for i in range(n):
        que.append((i, 1))
        lastdone.append(-1)
        next.append(0)
    while len(que) > 0:
        now, day = que.popleft()
        if lastdone[now] == day:
            continue
        if next[now] == n-1:
            continue
        candidate = a[now][next[now]]-1
        if lastdone[candidate] == day:
            continue
        if next[candidate] == n-1:
            continue
        if a[candidate][next[candidate]]-1 == now:
            next[now] += 1
            next[candidate] += 1
            lastdone[now] = day
            lastdone[candidate] = day
            que.append((now, day+1))
            que.append((candidate, day+1))

    for i in range(n):
        if next[i] != n-1:
            print(-1)
            return

    print(max(lastdone))

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
"""from collections import *
from itertools import *
from bisect import *
from heapq import *

import math
from fractions import gcd"""
import copy
N=int(input())
A=[list(reversed(list(map(int,input().split())))) for i in range(N)]
for i in range(N):
    for m in range(N-1):
        A[i][m]-=1

playerlst=set([i for i in range(N)])

count=0
nlst=copy.copy(playerlst)
while playerlst:
    flag=0
    lst=set()
    playedlst=set()
    while nlst:
        p=nlst.pop()
        if not p in lst and p in playerlst:
            p2=A[p][-1]
            if not p2 in lst and p2 in playerlst:
                if A[p2][-1]==p:
                    flag=1
                    A[p].pop()
                    A[p2].pop()
                    lst.add(p)
                    lst.add(p2)
                    if p2 in nlst:
                        nlst.remove(p2)
                    playedlst.add(p)
                    playedlst.add(p2)
                    if not A[p]:
                        playerlst.remove(p)
                    if not A[p2]:
                        playerlst.remove(p2)
    if not flag:
        print(-1)
        exit()
    count+=1
    nlst=copy.copy(playedlst)
print(count)

Submission status: Accepted

Solution code:
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

def main():
	N = INT()
	A = [LIST() for _ in range(N)]

	graph_out = defaultdict(list)
	graph_in = defaultdict(list)
	match_id = [[0]*N for _ in range(N)]

	def toid(i, j):  # 選手から試合IDに変換
		if i > j: i, j = j, i
		return match_id[i][j]

	cnt = 0
	for i in range(N):
		for j in range(N):
			if i < j:
				match_id[i][j] = cnt
				cnt += 1

	V = N*(N-1)//2
	gout = [[] for _ in range(V)]
	gin = [[] for _ in range(V)]
	deg = [0]*(V)
	for i in range(N):
		for j in range(N-2):
			gout[toid(i, A[i][j]-1)].append(toid(i, A[i][j+1]-1))
			deg[toid(i, A[i][j+1]-1)] += 1
			gin[toid(i, A[i][j+1]-1)].append(toid(i, A[i][j]-1))
	# トポロジカルソート
	ans = [v for v in range(V) if deg[v]==0]
	deq = deque(ans)
	used = [0]*V
	while deq:
	    v = deq.popleft()
	    for t in gout[v]:
	        deg[t] -= 1
	        if deg[t]==0:
	            deq.append(t)
	            ans.append(t)
	if any(deg):
		print(-1)
		exit()

	cnt = [0]*V  # cntが入り次数に達したら発火
	day = [0]*V
	q = deque(ans)
	ans = 0

	while q:
		n = q.popleft()
		for node in gout[n]:
			cnt[node] += 1
			if cnt[node] == len(gin[node]):
				q.append(node)
				day[node] = day[n] + 1
				ans = day[node]
	print(ans+1) 

if __name__ == '__main__':
	main()

Submission status: Accepted

Solution code:
from collections import Counter,defaultdict,deque
from bisect import bisect_left
import sys,math,itertools,pprint,fractions,time
sys.setrecursionlimit(10**8)
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

st = time.time()
n = inp()
a = []
for i in range(n):
    b = inpl()
    a.append(deque(b))
zan = n*(n-1)//2
res = 0
while True:
    res += 1
    now = zan
    s = set()
    for i in range(n):
        if i in s or a[i] == deque([]): continue
        end = True
        chk = a[i][0] - 1
        if not chk in s and a[chk][0] == i+1:
            zan -= 1
            if not zan: 
                print(res); quit()
            a[i].popleft(); a[chk].popleft()
            s.add(i); s.add(chk)
        # print(res,i,chk,a)
        nnn = time.time()
    if now == zan:
        print(-1)
        quit()
    if nnn - st > 1.7:
        print(n*(n-1)//2)
        quit()

Submission status: Accepted

Solution code:
import collections

n=int(input())
arr=[list(map(int,input().split())) for _ in range(n)]
arr=[0]+[collections.deque(arr[i]) for i in range(n)]
ans=0
cand=set(range(1,n+1))
while 1:
  check=set()
  for i in cand:
    if not arr[i]:
      continue
    pair=arr[i][0]
    if arr[pair][0]==i:
      check.add(i)
      check.add(pair)
  if not check:
    break
  cand=set()
  for i in check:
    cand.add(i)
    arr[i].popleft()
    if arr[i]:
      cand.add(arr[i][0])
  ans+=1
for i in range(1,n+1):
  if arr[i]:
    print(-1)
    break
else:
  print(ans)

Submission status: Accepted

Solution code:
n = int(input())
g = [[-1, -1] for i in range(n*n)]
z = [0] * (n*n)

a = []
for _ in range(n):
    a.append([int(i) for i in input().split()])

for i in range(n):
    for j in range(n-2):
        p, q = (i, a[i][j]-1)
        r, s = (i, a[i][j+1]-1)
        r, s = (min(r, s), max(r ,s))
        if p < q:
            g[p*n+q][0] = r*n + s
        else:
            g[q*n+p][1] = r*n + s
        z[r*n+s] += 1

qu = set([])
for i in range(n):
    p, q = (i, a[i][0]-1)
    p, q = (min(p, q), max(p ,q))
    if z[p*n+q] == 0:
        qu.add(p*n+q)

ans = 0
re = 0
while True:
    nqu = []
    while qu:
        s = qu.pop()
        re += 1
        for t in g[s]:
            if t != -1:
                z[t] -= 1
                if z[t] == 0:
                    nqu.append(t)
    ans += 1    
    qu = nqu
    if not qu:
        break

if re == n*(n-1)//2:
    print(ans)
else:
    print(-1)

Submission status: Accepted

Solution code:
from collections import deque
n = int(input())
a = []
for i in range(n):
    a1 = list(map(int,input().split()))
    a.append(a1)
l = [[[] for i in range(n)] for i in range(n)]
c = 0
day = 0
for i in range(n):
    ap = [i,a[i][0]-1]
    ap.sort()
    for j in range(1,n-1):
        p = [i,a[i][j]-1]
        p.sort()
        l[ap[0]][ap[1]].append(p)
        ap = p
rl = [[0 for i in range(n)] for i in range(n)]
dl = [[0 for i in range(n)] for i in range(n)]
d = deque()
for i in range(n):
    for j in range(n):
        if i < j:
            if len(l[i][j]) > 0:
                for k in l[i][j]:
                    rl[k[0]][k[1]] += 1
#print(rl)
for i in range(n):
    for j in range(n):
        if i < j:
            if rl[i][j] == 0:
                d.append([[i,j],0])
al = []
key = 0
#print(l)
if len(d) == 0:
    key = 1
while len(d):
    #print(d)
    now,day = d.pop()
    day += 1
    if len(l[now[0]][now[1]]) == 0:
        al.append(day)
    else:
        for i in l[now[0]][now[1]]:
            if rl[i[0]][i[1]] == 1:
                rl[i[0]][i[1]] -= 1
                d.append([i,max(day,dl[i[0]][i[1]])])
            else:
                rl[i[0]][i[1]] -= 1
                dl[i[0]][i[1]] = max(day,dl[i[0]][i[1]])
    if day > n*(n-1)//2:
        key = 1
        break
md = 0
for i in range(n):
    md += sum(rl[i])
if key == 1 or md > 0:
    print(-1)
else:
    print(max(al))

Submission status: Accepted

Solution code:
n=int(input())
import time
T=time.time()
data_set=[0 for i in range(n)]
for i in range(n):
    a=list(map(int,input().split()))
    a.append(-1)
    data_set[i]=a
index=[0 for i in range(n)]
ans=-1
flag=True
semi=False
now=[data_set[i][index[i]] for i in range(n)]
finished=[False for i in range(n)]
while flag:
    visited=[False for i in range(n)]
    sub=False
    for i in range(n):
        #nowリストのうち日ありからi+1番目のものについての一致条件の確認
        K=now[i]
        if now[K-1]==i+1 and not(visited[i] or visited[K-1]) and not(finished[i] or finished[K-1]):
                    visited[i]=True
                    visited[K-1]=True
                    index[i]+=1
                    index[K-1]+=1
                    sub=True
                    if index[i]==n-1:
                        finished[i]=True             
                    now[i]=data_set[i][index[i]]
                    if index[K-1]==n-1:
                        finished[K-1]=True                   
                    now[K-1]=data_set[K-1][index[K-1]]
    if not sub:
        flag=False
    if time.time()-T>1.5:
        flag=False
        semi=True
    ans+=1
judge=True
for i in range(n):
  if finished[i]==False:
    judge=False
    break
if judge:
  print(ans)
else:
  if not semi:
    print(-1)
  if semi:
    print(499500)

Submission status: Accepted

Solution code:
from sys import stdout
printn = lambda x: stdout.write(str(x))
inn = lambda : int(input())
inl   = lambda: list(map(int, input().split()))
inm   = lambda:      map(int, input().split())
ins = lambda : input().strip()
DBG = True  and False
BIG = 999999999
R = 10**9 + 7

def ddprint(x):
  if DBG:
    print(x)

#from collections import defaultdict,deque
n = inn()
pr = [[ [] for i in range(n+1) ] for j in range(n+1)]
ch = [[ [] for i in range(n+1) ] for j in range(n+1)]
for i in range(1,n+1):
    a = inl()
    for j in range(n-2):
        x1 = x2 = i
        y1 = a[j]
        y2 = a[j+1]
        if x1>y1:
            x1,y1 = y1,x1
        if x2>y2:
            x2,y2 = y2,x2
        ch[x1][y1].append((x2,y2))
        pr[x2][y2].append((x1,y1))
g = [ [0]*(n+1) for i in range(n+1) ]
q = []
for i in range(1,n):
    for j in range(i+1,n+1):
        if len(pr[i][j])==0:
            q.append((i,j))
            g[i][j] = 1
        else:
            g[i][j] = 0
ddprint(ch)
ddprint("pr")
ddprint(pr)
ddprint(g)
while len(q)>0:
    z = q.pop()
    i,j = z
    for u,v in ch[i][j]:
        g[u][v] = max(g[u][v], g[i][j]+1)
        #ddprint("y {} z {}".format(y,z))
        pr[u][v].remove(z)
        if len(pr[u][v])==0:
            #del pr[y]
            q.append((u,v))
ddprint("newg")
ddprint(g)
#gmn = [min(r[1:]) for r in g[1:]]
gmn = BIG
for i in range(1,n):
    for j in range(i+1,n+1):
        gmn = min(gmn,g[i][j])
if gmn==0:
    print(-1)
else:
    print(max([max(r) for r in g]))

Submission status: Accepted

Solution code:
from sys import setrecursionlimit as SRL, stdin

SRL(10 ** 7)
rd = stdin.readline
rrd = lambda: map(int, rd().strip().split())

q = [[]]
l = [0] * 1005
d = [0] * 1005
hv = [0] * 1005

def dfs(x,y):
    hv[x] = 1
    for i in range(l[x],n-1):

        if q[x][i] == y:
            l[x] = i+1
            hv[x] = 0

            d[q[x][i]] += 1
            d[x] += 1
            d[x] = max(d[x],d[q[x][i]])
            d[q[x][i]] = max(d[x], d[q[x][i]])

            return
        if hv[q[x][i]]:
            print(-1)
            exit(0)
        dfs(q[x][i],x)
        d[x] = max(d[q[x][i]],d[x])


    hv[x] = 0
    l[x] = n

n = int(input())
for i in range(n):
    a = list(rrd())
    q.append(a)

for i in range(1,n+1):
    dfs(i,0)

print(max(d))

Submission status: Accepted

Solution code:
def examA():
    N = I()
    ans = 0
    print(ans)
    return

def examB():
    ans = 0
    print(ans)
    return

def examC():
    ans = 0
    print(ans)
    return

def examD():
    ans = 0
    print(ans)
    return

def examE():
    N = I()
    node = N*(N-1)//2
    V = [[]for _ in range(node)]
    D = [[0]*N for _ in range(N)]
    cur = 0
    for i in range(N):
        for j in range(i+1,N):
            D[i][j] = cur
            D[j][i] = cur
            cur += 1
    #A = [LI() for _ in range(N)]
    for i in range(N):
        a = LI()
        for j in range(N-2):
            fr = D[i][a[j]-1]
            to = D[i][a[j+1]-1]
            #print(fr,to)
            V[fr].append(to)

    visited = [False] * node
    calculated = [False] * node
    dp = [1] * node
    # https://mhiro216.hatenablog.com/entry/2019/09/08/142414
    def dfs(v):
        if visited[v]:
            if not calculated[v]:
                return -1  # 計算が終わっていない頂点を2度訪れるのはループがあるということ
            return dp[v]
        visited[v] = True
        for u in V[v]:  # 全ての辺をなめる
            res = dfs(u)
            if res == -1: return -1  # ループがあれば-1を返す
            elif res+1>dp[v]:
                dp[v] = res + 1
        calculated[v] = True
        return dp[v]

    ans = 0
    for i in range(node):
        res = dfs(i)
        ans = max(ans,res)
        if res == -1:
            print('-1')  # ループがあれば-1を返す（問題文の指示）
            return
    print(ans)
    return

def examF():
    ans = 0
    print(ans)
    return

import sys,copy,bisect,itertools,heapq,math,random
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet,_ep
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
_ep = 10**(-12)
alphabet = [chr(ord('a') + i) for i in range(26)]

sys.setrecursionlimit(10**6)

if __name__ == '__main__':
    examE()

"""

"""

Submission status: Accepted

Solution code:
N = int(input())
A = [list(map(lambda x: int(x) - 1, input().split())) + [-1] for i in range(N)]

ans = 0
matched = 0
marker = [0] * N
que = list(range(N))

while matched < N * (N - 1) // 2:
    already_matched = set()
    next_que = []

    while que:
        player = que.pop()
        partner = A[player][marker[player]]

        if A[partner][marker[partner]] == player:
            if not ((player not in already_matched) and (partner not in already_matched)):
                continue

            matched += 1

            marker[player] += 1
            marker[partner] += 1

            already_matched.add(player)
            already_matched.add(partner)

            next_que.append(player)
            next_que.append(partner)

    if not next_que:
        print(-1)
        break

    ans += 1
    que = next_que[:]

else:
    print(ans)

Submission status: Accepted

Solution code:
from collections import defaultdict
N = int(input())
dic = defaultdict(list)
toNum = {}
L = N*(N-1)//2
s = [0]
for i in range(N-1,0,-1):
  s += [s[-1]+i]
dist = [0]*L
for i in range(N):
  inf = [int(c)-1 for c in input().split()]
  pa = min(i,inf[0])
  pb = max(i,inf[0])
  pnum = s[pa]+(pb-pa-1)
  for j in range(1,N-1):
    a = min(i,inf[j])
    b = max(i,inf[j])
    num = s[a]+(b-a-1)
    dic[pnum]  += [num]
    dist[num] += 1
    pa = a
    pb = b
    pnum = num

hq = []
ans = 0
for i in range(L):
  if dist[i]==0:
    hq += [i]
while hq:
  ans += 1
  nq = []
  for e in hq:
    for p in dic[e]:
      if dist[p]==0:
        continue
      dist[p] -= 1
      if dist[p]==0:
        nq += [p]
  hq = nq
if sum(dist) != 0:
  ans = -1
print(ans)

Submission status: Accepted

Solution code:
N = int(input())
A = [0 for i in range(N)]
for i in range(N):
  A[i] = [-1]+[int(c)-1 for c in input().split()][::-1]

def f(cand):
  can_use = []
  candl = set()
  for i in cand:
    c = A[i][-1]
    if A[c][-1]==i:
      can_use += [i]
  for n in can_use:
    A[n].pop()
    candl.add(n)
    if A[n][-1]!=-1:
      candl.add(A[n][-1])
  return len(can_use),candl

ans = 0
rest = N*(N-1)
cand = set(range(N))
while True:
  ans += 1
  x, cand = f(cand)
  if x==0:
    ans = -1
    break
  rest -= x
  if rest==0:
    break
print(ans)

Submission status: Accepted

Solution code:
import sys
from collections import deque

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

N = ir()
A = [deque(lr()) for _ in range(N)]
candidate = list(range(N))
match = 0
day = 0

while True:
    day += 1
    used = set()
    next = set()
    bool = False
    for c in candidate:
        if len(A[c]) == 0:
            continue
        op = A[c][0] - 1
        if c in used or op in used:
            continue
        if A[op][0] - 1 == c:
            bool = True
            A[c].popleft()
            A[op].popleft()
            match += 1
            next |= {c, op}
            used |= {c, op}
    if match == N * (N-1) // 2:
        break
    if not bool:
        print(-1)
        exit()
    candidate = next

print(day)

Submission status: Accepted

Solution code:
from collections import deque

def func(x):
    return x - 1

def main():
    N = int(input())
    A = [deque(map(func,map(int, input().split()))) for _ in range(N)]
    # 前日試合した人
    pre_players = range(N)
    game_cnt = 0
    day_cnt = 0
    max_cnt = N * (N - 1) // 2
    while day_cnt < max_cnt:
        # 当日試合した人
        players = set()
        for p in pre_players:
            if p in players:
                continue
            if not A[p]:
                continue
            opp = A[p][0]
            if opp in players:
                continue

            if p == A[opp][0]:
                A[p].popleft()
                A[opp].popleft()
                players |= {p,opp}
                game_cnt += 1

        pre_players = players
        day_cnt += 1

        if max_cnt == game_cnt:
            break

    if game_cnt != max_cnt:
        print(-1)
    else:
        print(day_cnt)
    
    

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
from collections import deque

N = int(input())
l = [deque([])]+[deque(map(int, input().split())) for _ in range(N)]

v = 0
ans = 0
t = N*(N-1)//2

last_used = set(range(1, N+1))
while v<t and ans<t:
    used = set()
    for n in last_used:
        if n in used:continue
        if not l[n]:continue
        pair = l[n][0]
        b = l[pair][0]
        if pair in used:continue

        if b==n:
            l[n].popleft()
            l[pair].popleft()
            used|={n,pair}
            v += 1
    last_used = used
    ans += 1

if ans==t and ans!=v:
    print(-1)
else:
    print(ans)

Submission status: Accepted

Solution code:
import sys
import collections
import copy

input = sys.stdin.readline


def main():
    N = int(input())
    A = [collections.deque([int(x) for x in input().split()]) for _ in range(N)]

    day = 0
    c = 0
    nxt = [x for x in range(N)]
    oppo = [0] * N

    while c != N * (N - 1):
        day += 1

        for i in nxt:
            oppo[i] = A[i].popleft() if A[i] else -1

        tmp = set()
        for i in nxt:
            if i == -1 or i in tmp:
                continue
            if i == oppo[oppo[i] - 1] - 1:
                tmp.add(i)
                tmp.add(oppo[i] - 1)
                c += 2
        if not tmp:
            print(-1)
            return

        nxt = tmp

    print(day)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
N = int(input())
A = [list(map(lambda x: int(x) - 1, input().split())) + [-1] for i in range(N)]

ans = 0
matched = 0
marker = [0] * N
que = list(range(N))

while matched < N * (N - 1) // 2:
    already_matched = set()
    no_matched = True
    next_que = []

    while que:
        player = que.pop()
        partner = A[player][marker[player]]

        if A[partner][marker[partner]] == player:
            if not ((player not in already_matched) and (partner not in already_matched)):
                continue

            matched += 1

            marker[player] += 1
            marker[partner] += 1

            already_matched.add(player)
            already_matched.add(partner)

            next_que.append(player)
            next_que.append(partner)

            no_matched = False

    ans += 1
    que = next_que[:]
    if no_matched:
        print(-1)
        break

else:
    print(ans)

Submission status: Accepted

Solution code:
N = int(input())

G = [list(map(int, input().split())) for _ in range(N)]
cur = [0] * N
edge = [0] * N
for i in range(N):
    edge[i] = G[i][0] - 1

day = 0
player = set(range(N))
cnt = 0
while len(player) > 0:
    day += 1
    game = set()
    for i in player:
        e = edge[i]
        if i == edge[e] and i != e:
            game.add(i)
            game.add(e)
    player = set()
    for j in game:
        cur[j] += 1
        c = cur[j]
        if c >= N - 1:
            edge[j] = j
        else:
            edge[j] = G[j][c] - 1
            player.add(j)

if min(cur) != N - 1:
    ans = -1
else:
    ans = day
print(ans)