Problem:


Score : 400 points

Problem Statement

Given is a tree G with N vertices.
The vertices are numbered 1 through N, and the i-th edge connects Vertex a_i and Vertex b_i.

Consider painting the edges in G with some number of colors.
We want to paint them so that, for each vertex, the colors of the edges incident to that vertex are all different.

Among the colorings satisfying the condition above, construct one that uses the minimum number of colors.

Constraints

 2 \le N \le 10^5

 1 \le a_i \lt b_i \le N

All values in input are integers.

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
\vdots
a_{N-1} b_{N-1}

Output

Print N lines.

The first line should contain K, the number of colors used.

The (i+1)-th line (1 \le i \le N-1) should contain c_i, the integer representing the color of the i-th edge, where 1 \le c_i \le K must hold.

If there are multiple colorings with the minimum number of colors that satisfy the condition, printing any of them will be accepted.

Sample Input 1

3
1 2
2 3

Sample Output 1

2
1
2

Sample Input 2

8
1 2
2 3
2 4
2 5
4 7
5 6
6 8

Sample Output 2

4
1
2
3
4
1
1
2

Sample Input 3

6
1 2
1 3
1 4
1 5
1 6

Sample Output 3

5
1
2
3
4
5



Sample input:
3
1 2
2 3


Sample output:
2
1
2

Submission status: Time Limit Exceeded

Solution code:
#nord_aで使っている色の＋１
#初期入力
import sys
input = sys.stdin.readline
import heapq
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            =[i for i in range(N-1)]
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A[i] =a,b            #色を出力するため

#色の数(各頂点の最大値)
color_max =0
root =0
for i,v in connection.items():
    if color_max < len(v) :
        color_max =len(v)
        root =i         #枝が一番多い所を根 ⇒スタート

#各頂点に色を準備⇒辺の色決定
aa=[]
color =0                                 #辺に塗る色の候補
color_node ={i:[] for i in range(1,N+1)} #頂点に使った色の管理
color_edge ={}
for a,b in A:
    color_edge[(a,b)] =-1                   #辺の色 -1で初期化
now_set =set() #=start
now_set.add(root) #=start
next =set()
next_next =set()
passed =set()
count =0
while -1 in color_edge.values():
        for now in now_set: #幅優先探索
            next =connection[now]
            for nex_2 in next:
                count =0
                #while count < color_max:
                q,color =divmod(color,color_max)
                if color not in color_node[now] and color not in color_node[nex_2]:
                    n1,n2=0,0
                    if now > nex_2:
                        n1,n2 =nex_2,now
                    else:
                        n1,n2 =now,nex_2
                    color_edge[(n1,n2)] =color +1  #辺の色決定
                    color_node[now]     .append(color)
                    color_node[nex_2]   .append(color)
                    passed              .add(now)
                    if connection[nex_2] not in passed:
                        next_next       .add(nex_2)  #つながっている頂点（次に探索する）
                    passed      .add(nex_2)
                    color       +=1
                    #count       +=1
                else:
                    color +=1
                    #count +=1
        now_set     .clear()
        now_set     |=next_next
        next_next   .clear()
    
#出力
print(color_max)
for i in A:
    print(color_edge[i])

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-

#############
# Libraries #
#############

import sys
input = sys.stdin.readline

import math
from collections import deque
from fractions import gcd
from functools import lru_cache


#############
# Constants #
#############

MOD = 10**9+7
INF = float('inf')

#############
# Functions #
#############

######INPUT######
def inputI(): return int(input().strip())
def inputS(): return input().strip()
def inputIL(): return list(map(int,input().split()))
def inputSL(): return list(map(str,input().split()))
def inputILs(n): return list(int(input()) for _ in range(n))
def inputSLs(n): return list(input().strip() for _ in range(n))
def inputILL(n): return [list(map(int, input().split())) for _ in range(n)]
def inputSLL(n): return [list(map(str, input().split())) for _ in range(n)]

#####Inverse#####
def inv(n): return pow(n, MOD-2, MOD)

######Combination######
kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n):
    return kaijo_memo[n]
  if(len(kaijo_memo) == 0):
    kaijo_memo.append(1)
  while(len(kaijo_memo) <= n):
    kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n):
    return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0):
    gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n):
    gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if(n == r):
    return 1
  if(n < r or r < 0):
    return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret

######Factorization######
def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])
    if temp!=1:
        arr.append([temp, 1])

    if arr==[]:
        arr.append([n, 1])
    return arr

#####LCM#####
def lcm(a, b):
    return a * b // gcd (a, b)

#############
# Main Code #
#############

N = inputI()

graph = [[] for _ in range(N)]
for i in range(N-1):
    u, v = inputIL()
    graph[u-1].append((v-1,i))
    graph[v-1].append((u-1,i))
  
M = 0
root = 0
for i in range(N):
  l = graph[i]
  n = len(l)
  if n > M:
    root = i
    M = n

color = [None for _ in range(N-1)]
q = deque([(root,-1,-1)])

while  q:
  u,prev,prev_p = q.popleft()
  c = set(range(M))
  todo = []
  tonari = set(graph[u])
  if prev != -1:
    c.remove(color[prev])
    tonari.remove((prev_p,prev))
  for item in tonari:
    v = item[0]
    i = item[1]
    color[i] = c.pop()
    q.append((v,i,u))
  
print(M)
for i in color:
  print(i+1)

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-

#############
# Libraries #
#############

import sys
input = sys.stdin.readline

import math
from collections import deque
from fractions import gcd
from functools import lru_cache


#############
# Constants #
#############

MOD = 10**9+7
INF = float('inf')

#############
# Functions #
#############

######INPUT######
def inputI(): return int(input().strip())
def inputS(): return input().strip()
def inputIL(): return list(map(int,input().split()))
def inputSL(): return list(map(str,input().split()))
def inputILs(n): return list(int(input()) for _ in range(n))
def inputSLs(n): return list(input().strip() for _ in range(n))
def inputILL(n): return [list(map(int, input().split())) for _ in range(n)]
def inputSLL(n): return [list(map(str, input().split())) for _ in range(n)]

#####Inverse#####
def inv(n): return pow(n, MOD-2, MOD)

######Combination######
kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n):
    return kaijo_memo[n]
  if(len(kaijo_memo) == 0):
    kaijo_memo.append(1)
  while(len(kaijo_memo) <= n):
    kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n):
    return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0):
    gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n):
    gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if(n == r):
    return 1
  if(n < r or r < 0):
    return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret

######Factorization######
def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])
    if temp!=1:
        arr.append([temp, 1])

    if arr==[]:
        arr.append([n, 1])
    return arr

#####LCM#####
def lcm(a, b):
    return a * b // gcd (a, b)

#############
# Main Code #
#############

N = inputI()

graph = [[] for _ in range(N)]
for i in range(N-1):
    u, v = inputIL()
    graph[u-1].append((v-1,i))
    graph[v-1].append((u-1,i))
  
M = 0
root = 0
for i in range(N):
  l = graph[i]
  n = len(l)
  if n > M:
    root = i
    M = n

color = [None for _ in range(N-1)]
q = deque([root])

while  q:
  u = q.popleft()
  c = set(range(M))
  todo = []
  for v in graph[u]:
    i = v[1]
    v = v[0]
    if color[i] == None:
      todo.append(i)
      q.append(v)
    else:
      c.remove(color[i])
  for i in todo:
    color[i] = c.pop()
  
print(M)
for i in color:
  print(i+1)

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
import sys
import math
from bisect import bisect_left
from bisect import bisect_right
import collections
import copy
import heapq
from collections import defaultdict
from heapq import heappop, heappush
import itertools
input = sys.stdin.readline
from collections import defaultdict
from heapq import heappop, heappush

from decimal import *

##### リストの 二分木検索 #####
# bisect_left(lists, 3)
# bisect_right(lists, 3)

##### プライオリティキュー #####
# heapq.heapify(a) #リストaのheap化
# heapq.heappush(a,x) #heap化されたリストaに要素xを追加
# heapq.heappop(a) #heap化されたリストaから最小値を削除＆その最小値を出力

# heapq.heappush(a, -x) #最大値を取り出す時は、pushする時にマイナスにして入れよう
# heapq.heappop(a) * (-1) #取り出す時は、-1を掛けて取り出すこと

##### タプルリストのソート #####
# sorted(ans) #(a, b) -> 1st : aの昇順, 2nd : bの昇順
# sorted(SP, key=lambda x:(x[0],-x[1])) #(a, b) -> 1st : aの昇順, 2nd : bの降順
# sorted(SP, key=lambda x:(-x[0],x[1])) #(a, b) -> 1st : aの降順, 2nd : bの昇順
# sorted(SP, key=lambda x:(-x[0],-x[1])) #(a, b) -> 1st : aの降順, 2nd : bの降順

# sorted(SP, key=lambda x:(x[1])) #(a, b) -> 1st : bの昇順
# sorted(SP, key=lambda x:(-x[1])) #(a, b) -> 1st : bの降順

##### 累乗 #####
# pow(x, y, z) -> x**y % z

##### 割り算の切り上げ #####
# tmp = -(-4 // 3)

##### dict の for文 #####
# for k, v in d.items():
#     print(k, v)

def inputInt(): return int(input())
def inputMap(): return map(int, input().split())
def inputList(): return list(map(int, input().split()))
def inputStr(): return input()[:-1]

inf = float('inf')
mod = 1000000007

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

def main():
	N = inputInt()
	ki = [[] for i in range(N)]
	inp = {}
	ans = [inf for i in range(N-1)]
	ansInt = 0

	for i in range(N-1):
		a,b = inputMap()
		a -= 1
		b -= 1
		ki[a].append(b)
		ki[b].append(a)
		inp[(a,b)] = i

	for i in ki:
		if len(i) > ansInt:
			ansInt = len(i)

	for i in range(N):
		ko = ki[i]
		dame = []
		mi = []
		for j in ko:
			#print("{} {} {}".format(i,j,ko))
			if i < j:
				mi.append(j)
			else:
				dame.append(ans[inp[(j,i)]])
		for j in mi:
			for ii in range(ansInt+1):
				tmp = bisect_right(dame, ii)
				if ii in dame:
					pass
				else:
					ans[inp[(i,j)]] = ii
					dame.append(ii)
					break
		#print(ans)

	#print(ki)
	#print(inp)
	#print(ans)

	print(ansInt)
	for i in ans:
		print(i+1)

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
# N 個のボールを K グループに分ける場合のパターン数
def sunuke(N, K, mod=10**9+7):
	if N < K or K-1 < 0:
		return 0
	else:
		return combination(N-1, K-1, mod)

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
# nCr mod m
# rがn/2に近いと非常に重くなる
def combination(n, r, mod=10**9+7):
    r = min(r, n-r)
    res = 1
    for i in range(r):
        res = res * (n - i) * modinv(i+1, mod) % mod
    return res

# mを法とするaの乗法的逆元
def modinv(a, mod=10**9+7):
    return pow(a, mod-2, mod)

def egcd(a, b):
    if a == 0:
        return b, 0, 1
    else:
        g, y, x = egcd(b % a, a)
        return g, x - (b // a) * y, y

# nHr mod m
# 問題によって、combination()を切り替えること
def H(n, r, mod=10**9+7):
	# comb = Combination(n+r-1, mod)
	# return comb(n+r-1, r)
    return combination(n+r-1, r, mod)


class Combination:
    """
    O(n)の前計算を1回行うことで，O(1)でnCr mod mを求められる
    n_max = 10**6のとき前処理は約950ms (PyPyなら約340ms, 10**7で約1800ms)
    使用例：
    comb = Combination(1000000)
    print(comb(5, 3))  # 10
    """
    def __init__(self, n_max, mod=10**9+7):
        self.mod = mod
        self.modinv = self.make_modinv_list(n_max)
        self.fac, self.facinv = self.make_factorial_list(n_max)

    def __call__(self, n, r):
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n-r] % self.mod

    def make_factorial_list(self, n):
        # 階乗のリストと階乗のmod逆元のリストを返す O(n)
        # self.make_modinv_list()が先に実行されている必要がある
        fac = [1]
        facinv = [1]
        for i in range(1, n+1):
            fac.append(fac[i-1] * i % self.mod)
            facinv.append(facinv[i-1] * self.modinv[i] % self.mod)
        return fac, facinv

    def make_modinv_list(self, n):
        # 0からnまでのmod逆元のリストを返す O(n)
        modinv = [0] * (n+1)
        modinv[1] = 1
        for i in range(2, n+1):
            modinv[i] = self.mod - self.mod//i * modinv[self.mod%i] % self.mod
        return modinv

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
# dfs のサンプル
def dfs(graph,parent,counter,edge):
    stk = []
    stk.append(edge)
    while len(stk) > 0:
        p = stk.pop()
        for e in graph[p]:
            if parent[p] == e:
                continue
            else:
                parent[e] = p
                counter[e] += counter[p]
                stk.append(e)

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
if __name__ == "__main__":
	main()

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
import sys
import math
from bisect import bisect_left
from bisect import bisect_right
import collections
import copy
import heapq
from collections import defaultdict
from heapq import heappop, heappush
import itertools
input = sys.stdin.readline
from collections import defaultdict
from heapq import heappop, heappush

from decimal import *

##### リストの 二分木検索 #####
# bisect_left(lists, 3)
# bisect_right(lists, 3)

##### プライオリティキュー #####
# heapq.heapify(a) #リストaのheap化
# heapq.heappush(a,x) #heap化されたリストaに要素xを追加
# heapq.heappop(a) #heap化されたリストaから最小値を削除＆その最小値を出力

# heapq.heappush(a, -x) #最大値を取り出す時は、pushする時にマイナスにして入れよう
# heapq.heappop(a) * (-1) #取り出す時は、-1を掛けて取り出すこと

##### タプルリストのソート #####
# sorted(ans) #(a, b) -> 1st : aの昇順, 2nd : bの昇順
# sorted(SP, key=lambda x:(x[0],-x[1])) #(a, b) -> 1st : aの昇順, 2nd : bの降順
# sorted(SP, key=lambda x:(-x[0],x[1])) #(a, b) -> 1st : aの降順, 2nd : bの昇順
# sorted(SP, key=lambda x:(-x[0],-x[1])) #(a, b) -> 1st : aの降順, 2nd : bの降順

# sorted(SP, key=lambda x:(x[1])) #(a, b) -> 1st : bの昇順
# sorted(SP, key=lambda x:(-x[1])) #(a, b) -> 1st : bの降順

##### 累乗 #####
# pow(x, y, z) -> x**y % z

##### 割り算の切り上げ #####
# tmp = -(-4 // 3)

##### dict の for文 #####
# for k, v in d.items():
#     print(k, v)

def inputInt(): return int(input())
def inputMap(): return map(int, input().split())
def inputList(): return list(map(int, input().split()))
def inputStr(): return input()[:-1]

inf = float('inf')
mod = 1000000007

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

def main():
	N = inputInt()
	ki = [[] for i in range(N)]
	inp = {}
	ans = [inf for i in range(N-1)]
	ansInt = 0

	for i in range(N-1):
		a,b = inputMap()
		a -= 1
		b -= 1
		ki[a].append(b)
		ki[b].append(a)
		inp[(a,b)] = i

	for i in ki:
		if len(i) > ansInt:
			ansInt = len(i)

	for i in range(N):
		ko = ki[i]
		dame = []
		for j in ko:
			#print("{} {} {}".format(i,j,ko))
			if i < j:
				pass
			else:
				dame.append(ans[inp[(j,i)]])
		for j in ko:
			if i < j:
				for ii in range(ansInt+1):
					if ii in dame:
						pass
					else:
						ans[inp[(i,j)]] = ii
						dame.append(ii)
						break
		#print(ans)
	#print(ki)
	#print(inp)
	#print(ans)

	print(ansInt)
	for i in ans:
		print(i+1)

def dfs2(graph,parent,counter,edge):
    stk = []
    stk.append(edge)
    while len(stk) > 0:
        p = stk.pop()
        for e in graph[p]:
            if parent[p] == e:
                continue
            else:
                parent[e] = p
                counter[e] += counter[p]
                stk.append(e)

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
# N 個のボールを K グループに分ける場合のパターン数
def sunuke(N, K, mod=10**9+7):
	if N < K or K-1 < 0:
		return 0
	else:
		return combination(N-1, K-1, mod)

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
# nCr mod m
# rがn/2に近いと非常に重くなる
def combination(n, r, mod=10**9+7):
    r = min(r, n-r)
    res = 1
    for i in range(r):
        res = res * (n - i) * modinv(i+1, mod) % mod
    return res

# mを法とするaの乗法的逆元
def modinv(a, mod=10**9+7):
    return pow(a, mod-2, mod)

def egcd(a, b):
    if a == 0:
        return b, 0, 1
    else:
        g, y, x = egcd(b % a, a)
        return g, x - (b // a) * y, y

# nHr mod m
# 問題によって、combination()を切り替えること
def H(n, r, mod=10**9+7):
	# comb = Combination(n+r-1, mod)
	# return comb(n+r-1, r)
    return combination(n+r-1, r, mod)


class Combination:
    """
    O(n)の前計算を1回行うことで，O(1)でnCr mod mを求められる
    n_max = 10**6のとき前処理は約950ms (PyPyなら約340ms, 10**7で約1800ms)
    使用例：
    comb = Combination(1000000)
    print(comb(5, 3))  # 10
    """
    def __init__(self, n_max, mod=10**9+7):
        self.mod = mod
        self.modinv = self.make_modinv_list(n_max)
        self.fac, self.facinv = self.make_factorial_list(n_max)

    def __call__(self, n, r):
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n-r] % self.mod

    def make_factorial_list(self, n):
        # 階乗のリストと階乗のmod逆元のリストを返す O(n)
        # self.make_modinv_list()が先に実行されている必要がある
        fac = [1]
        facinv = [1]
        for i in range(1, n+1):
            fac.append(fac[i-1] * i % self.mod)
            facinv.append(facinv[i-1] * self.modinv[i] % self.mod)
        return fac, facinv

    def make_modinv_list(self, n):
        # 0からnまでのmod逆元のリストを返す O(n)
        modinv = [0] * (n+1)
        modinv[1] = 1
        for i in range(2, n+1):
            modinv[i] = self.mod - self.mod//i * modinv[self.mod%i] % self.mod
        return modinv

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
# dfs のサンプル
def dfs(graph,parent,counter,edge):
    stk = []
    stk.append(edge)
    while len(stk) > 0:
        p = stk.pop()
        for e in graph[p]:
            if parent[p] == e:
                continue
            else:
                parent[e] = p
                counter[e] += counter[p]
                stk.append(e)

#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
if __name__ == "__main__":
	main()

Submission status: Time Limit Exceeded

Solution code:
#nord_aで使っている色の＋１
#初期入力
import sys
input = sys.stdin.readline
import heapq
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            =[i for i in range(N-1)]
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A[i] =a,b            #色を出力するため

#色の数(各頂点の最大値)
color_max =0
for i in connection.values():
    color_max =max(color_max, len(i) )

#各頂点に色を準備⇒辺の色決定
aa=[]
color_node ={i:[] for i in range(1,N+1)} #頂点に使った色の管理
color_edge =[0]*(N-1)

for i in range(N-1):
    n_a,n_b = A[i] #n_a,n_b =i番目の辺とつながっている頂点
    if color_node[n_a] ==[]:
        color =0
    else:
        color =(color_node[n_a][-1]) +1
    while True:
        #color +=1
        q,color =divmod(color,color_max)
        if color not in color_node[n_a] and color not in color_node[n_b]: 
            color_edge[i] =color+1          #辺の色を出力用に決める。1～color_max
            color_node[n_a].append(color)    #前の頂点に使った色を追加、
            color_node[n_b].append(color)    #前の頂点に使った色を追加、

            break
        else:
            color +=1      
#出力
print(color_max)
for i in color_edge:
    print(i)

Submission status: Time Limit Exceeded

Solution code:
import sys
from collections import deque
input = sys.stdin.readline
N = int(input())
graph = [[] for _ in range(N)]
ab = [list(map(lambda x:int(x)-1, input().split())) for _ in range(N-1)]

col_max = 0
for i in range(N-1):
  a, b = ab[i]
  graph[a] += [b]
  graph[b] += [a]

for i in range(N):
  col_max = max(col_max, len(graph[i]))
print(col_max)

def bfs(s):
  q = deque([s])
  col = [0]*N
  col[s] = 1
  ad_col = [set() for _ in range(N)]
  edge_col = {}
  pre = -1

  while q:
    u = q.pop()
    col_q = deque([i for i in range(1, col_max+1) if i not in ad_col[u]])
    #print(u, col_q, ad_col)
    for v in graph[u]:
      if v != pre and col[v] == 0:
        c = col_q.popleft()
        col[v] = c
        q.append(v)
        ad_col[u].add(c)
        ad_col[v].add(c)
        edge_col[(u, v)] = c
        edge_col[(v, u)] = c
        pre = v
  return edge_col

col = bfs(0)
#print(col)

for a, b in ab:
  print(col[(a, b)])

Submission status: Time Limit Exceeded

Solution code:
N=int(input())
a=[0]*(N-1)
b=[0]*(N-1)
c=[0]*(N-1)
d=[[] for _ in range(N)]
e=[ set() for _ in range(N)] #存在する色のリスト
maxi=0
for i in range(N-1):
    a[i],b[i] = map(int,input().split())
    d[a[i]-1].append(b[i]-1)
    d[b[i]-1].append(a[i]-1)
for j in d:
    maxi=max(maxi,len(j))
for i in range(N-1):
    col=1
    while col in e[a[i]-1] or col in e[b[i]-1]:
        col +=1
        if col==maxi+1:
            col=1
    c[i]=col
    e[a[i]-1].add(col)
    e[b[i]-1].add(col)
   
print(maxi)
for color in c:
    print(color)

Submission status: Time Limit Exceeded

Solution code:
N=int(input())
a=[0]*(N-1)
b=[0]*(N-1)
c=[0]*(N-1)
d=[[] for _ in range(N)]
e=[ set() for _ in range(N)] #存在する色のリスト
maxi=0
for i in range(N-1):
    a[i],b[i] = map(int,input().split())
    d[a[i]-1].append(b[i]-1)
    d[b[i]-1].append(a[i]-1)
for j in d:
    maxi=max(maxi,len(j))
for i in range(N-1):
    col=1
    while col in e[a[i]-1] or col in e[b[i]-1]:
        col +=1
        if col==maxi+1:
            col=1
    c[i]=col
    e[a[i]-1].add(col)
    e[b[i]-1].add(col)
   
print(maxi)
for color in c:
    print(color)

Submission status: Time Limit Exceeded

Solution code:
#nord_aで使っている色の＋１
#初期入力
import sys
input = sys.stdin.readline
#from collections import deque
import heapq
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            =[[i] for i in range(N-1)]
A_sort =sorted(A)
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A_sort[i].append((a,b))             #色を出力するため
A_sort.sort(key=lambda x:x[1])
#色の数(各頂点の最大値)
color_max =0
for i in connection.values():
    color_max =max(color_max, len(i) )

#各頂点に色を準備⇒辺の色決定
aa=[]
hq_none =heapq.heapify(aa)
color_node ={i:[] for i in range(1,N+1)} #頂点に使った色の管理,dequeで高速？
for i in range(1,N+1):
    heapq.heapify(color_node[i])
color_edge =[0]*(N-1)

for i in range(N-1):
    n_a,n_b = A_sort[i][1] #i番目の辺とつながっている頂点
    if color_node[n_a] ==[]:
        color =0
    else:
        color =(color_node[n_a][0]) -1
    while True:
        #color +=1
        q,color =divmod(color,(-1)*color_max)
        if color not in color_node[n_a] and color not in color_node[n_b]: 
            #color_edge[i] =color+1          #辺の色を出力用に決める。1～color_max
            A_sort[i].append((-1)*color+1)     #辺の色を出力用に決める。1～color_max,A_sortに入れて、再度ソート
            heapq.heappush(color_node[n_a],color)    #前の頂点に使った色を追加、
            heapq.heappush(color_node[n_b],color)    #heapqの最大値出したいので*(-1)

            break
        else:
            color -=1      
#出力
print(color_max)
A_sort.sort()
for i in A_sort:
    print(i[2])

Submission status: Time Limit Exceeded

Solution code:
#nord_aで使っている色の＋１
#初期入力
import sys
input = sys.stdin.readline
from collections import deque
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            ={i:tuple() for i in range(1,N+1)}
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A[i]=a,b             #色を出力するため

#色の数(各頂点の最大値)
color_max =0
for i in connection.values():
    color_max =max(color_max, len(i) )

#各頂点に色を準備⇒辺の色決定
color_node ={i:deque() for i in range(1,N+1)} #頂点に使った色の管理,dequeで高速？
color_edge =[0]*(N-1)

for i in range(N-1):
    n_a,n_b = A[i] #i番目の辺とつながっている頂点
    if color_node[n_a] !=deque():
        color =color_node[n_a][-1] +1
    else:
        color =0
    while True:
        #color +=1
        q,color =divmod(color,color_max)
        if color not in color_node[n_a] and color not in color_node[n_b]: 
            color_edge[i] =color+1          #辺の色を出力用に決める。1～color_max
            color_node[n_a].append(color)    #前の頂点に使った色を追加
            color_node[n_b].append(color)    #先の頂点に使った色を追加
            break
        else:
            color +=1      
#出力
print(color_max)
print(*color_edge, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
#nord_aで使っている色の＋１
#初期入力
import sys
input = sys.stdin.readline
from collections import deque
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            ={i:tuple() for i in range(1,N+1)}
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A[i]=a,b             #色を出力するため

#色の数(各頂点の最大値)
color_max =0
for i in connection.values():
    color_max =max(color_max, len(i) )

#各頂点に色を準備⇒辺の色決定
color_node ={i:deque() for i in range(1,N+1)} #頂点に使った色の管理,dequeで高速？
color_edge =[0]*(N-1)

for i in range(N-1):
    n_a,n_b = A[i] #i番目の辺とつながっている頂点
    if color_node[n_a] !=deque():
        color =color_node[n_a][-1]
    else:
        color =0
    while True:
        #color +=1
        q,color =divmod(color,color_max)
        if color not in color_node[n_a] and color not in color_node[n_b]: 
            color_edge[i] =color+1          #辺の色を出力用に決める。1～color_max
            color_node[n_a].append(color)    #前の頂点に使った色を追加
            color_node[n_b].append(color)    #先の頂点に使った色を追加
            break
        else:
            color +=1      
#出力
print(color_max)
print(*color_edge, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
#初期入力
import sys
input = sys.stdin.readline
import random
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            ={i:tuple() for i in range(1,N+1)}
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A[i]=a,b             #色を出力するため

#色の数(各頂点の最大値)
color_max =0
for i in connection.values():
    color_max =max(color_max, len(i) )

#各頂点に色を準備⇒辺の色決定
A_sort =sorted(A)
color_node ={i:[] for i in range(1,N+1)} #頂点に使った色の管理
color_edge =[0]*(N-1)

#color_all =set(j for j in range(color_max) ) #0～color_max-1
for i in range(N-1):
    color =0
    while True:
        q,color =divmod(color,color_max)
        v_a,v_b = A[i] #i番目の辺とつながっている頂点
      
        if color not in color_node[v_a] and color not in color_node[v_b]: 
            color_edge[i] =color+1          #辺の色を出力用に決める。1～color_max
            color_node[v_a].append(color)    #前の頂点に使った色を追加
            color_node[v_b].append(color)    #先の頂点に使った色を追加
            break
        else:
            color +=1      
#出力
print(color_max)
print(*color_edge, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
#初期入力
import sys
input = sys.stdin.readline
import random
N = int(input())
connection   ={i:set() for i in range(1,N+1)}
A            ={i:tuple() for i in range(1,N+1)}
for i in range(N-1):
    a,b = (int(x) for x in input().split())
    connection[a].add(b) # つながりを逆向きも含めて入力
    connection[b].add(a) # 
    A[i]=a,b             #色を出力するため

#色の数(各頂点の最大値)
color_max =0
for i in connection.values():
    color_max =max(color_max, len(i) )

#各頂点に色を準備⇒辺の色決定
A_sort =sorted(A)
color_vertex ={i:set() for i in range(1,N+1)} #辺につながっている頂点に使った色
color_side =[0]*(N-1)

color_all =set(j for j in range(color_max) ) #0～color_max-1
for i in range(N-1):
    color =0
    while True:
        q,color =divmod(color,color_max)
        v_a,v_b = A[i] #i番目の辺とつながっている頂点
        #color =(color_all - color_vertex[v_a] -color_vertex[v_b]) #全ての色-使った色[a]-使った色[b]
        if color not in color_vertex[v_a] and color not in color_vertex[v_b]: 
            color_side[i] =color+1          #辺の色を出力用に決める。1～color_max
            color_vertex[v_a].add(color)    #前の頂点に使った色として追加
            color_vertex[v_b].add(color)    #先の頂点に使った色として追加
            break
        else:
            color +=1      
#出力
print(color_max)
print(*color_side, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
from collections import defaultdict, deque


def main():
    N = int(input())
    edges = list()
    adj_nodes = defaultdict(list)
    for _ in range(N - 1):
        a, b = list(map(int, input().split(' ')))
        a -= 1
        b -= 1
        edges.append((a, b))
        adj_nodes[a].append(b)
        adj_nodes[b].append(a)
    MAX_COLORS = max([len(nodes) for nodes in adj_nodes.values()])
    # BFS
    edge_colors = dict()
    frontier = deque()
    frontier.append((None, 0, None))  # from_node, to_node, color
    explored_nodes = [0]
    while len(frontier) > 0:
        n = frontier.popleft()
        explored_nodes.append(n[1])
        next_from_node = n[1]
        before_color = n[2] if n[2] is not None else (MAX_COLORS - 1)
        next_color = before_color
        next_to_nodes = adj_nodes[next_from_node]
        for next_to_node in next_to_nodes:
            if next_to_node in explored_nodes:
                continue
            next_color = (next_color + 1) % MAX_COLORS
            frontier.append((next_from_node, next_to_node, next_color))
            edge_colors[(next_from_node, next_to_node)] = next_color
            edge_colors[(next_to_node, next_from_node)] = next_color
    # print answer
    print(MAX_COLORS)
    for edge in edges:
        print(edge_colors[edge] + 1)


if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
import sys

input = sys.stdin.readline

N = int(input())

Graph = [[] for _ in range(N)]
edges = []

for _ in range(N - 1):
  a, b = [int(x) - 1 for x in input().split()]
  edges.append((a, b))
  
for a, b in edges:
  Graph[a].append(b)
  Graph[b].append(a)
  
k = max(len(edges) for edges in Graph)

colors = {color for color in range(1, k + 1)}
usedcolor = [None for _ in range(N)]
colored = {}

for v in range(N):
  unused_colors = colors - { usedcolor[v] }
  for edge in Graph[v]:
    # 未着色
    if (v, edge) not in colored and (edge, v) not in colored:
      color = unused_colors.pop()
      colored[(v, edge)] = colored[(edge, v)] = color
      usedcolor[edge] = color

print(k)

for a, b in edges:
  print(colored[(a, b)])

Submission status: Time Limit Exceeded

Solution code:
import sys

input = sys.stdin.readline

N = int(input())

Graph = [[] for _ in range(N)]
edges = []

for _ in range(N - 1):
  a, b = [int(x) - 1 for x in input().split()]
  edges.append((a, b))
  
for a, b in edges:
  Graph[a].append(b)
  Graph[b].append(a)
  
k = max(len(edges) for edges in Graph)

colors = {color for color in range(1, k + 1)}
usedcolor_sets = [set() for _ in range(N)]
colored = {}

for v in range(N):
  unused_colors = colors - usedcolor_sets[v]  
  for edge in Graph[v]:
    # 未着色
    if (v, edge) not in colored and (edge, v) not in colored:
      color = unused_colors.pop()
      colored[(v, edge)] = colored[(edge, v)] = color
      usedcolor_sets[edge].add(color)

print(k)

for a, b in edges:
  print(colored[(a, b)])