Problem:


Score : 400 points

Problem Statement

An SNS has N users - User 1, User 2, \cdots, User N.

Between these N users, there are some relationships - M friendships and K blockships.

For each i = 1, 2, \cdots, M, there is a bidirectional friendship between User A_i and User B_i.

For each i = 1, 2, \cdots, K, there is a bidirectional blockship between User C_i and User D_i.

We define User a to be a friend candidate for User b when all of the following four conditions are satisfied:

a \neq b.

There is not a friendship between User a and User b.

There is not a blockship between User a and User b.

There exists a sequence c_0, c_1, c_2, \cdots, c_L consisting of integers between 1 and N (inclusive) such that c_0 = a, c_L = b, and there is a friendship between User c_i and c_{i+1} for each i = 0, 1, \cdots, L - 1.

For each user i = 1, 2, ... N, how many friend candidates does it have?

Constraints

All values in input are integers.

2 ≤ N ≤ 10^5

0 \leq M \leq 10^5

0 \leq K \leq 10^5

1 \leq A_i, B_i \leq N

A_i \neq B_i

1 \leq C_i, D_i \leq N

C_i \neq D_i

(A_i, B_i) \neq (A_j, B_j) (i \neq j)

(A_i, B_i) \neq (B_j, A_j)

(C_i, D_i) \neq (C_j, D_j) (i \neq j)

(C_i, D_i) \neq (D_j, C_j)

(A_i, B_i) \neq (C_j, D_j)

(A_i, B_i) \neq (D_j, C_j)

Input

Input is given from Standard Input in the following format:

N M K
A_1 B_1
\vdots
A_M B_M
C_1 D_1
\vdots
C_K D_K

Output

Print the answers in order, with space in between.

Sample Input 1

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

Sample Output 1

0 1 0 1

There is a friendship between User 2 and 3, and between 3 and 4. Also, there is no friendship or blockship between User 2 and 4. Thus, User 4 is a friend candidate for User 2.

However, neither User 1 or 3 is a friend candidate for User 2, so User 2 has one friend candidate.

Sample Input 2

5 10 0
1 2
1 3
1 4
1 5
3 2
2 4
2 5
4 3
5 3
4 5

Sample Output 2

0 0 0 0 0

Everyone is a friend of everyone else and has no friend candidate.

Sample Input 3

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

Sample Output 3

1 3 5 4 3 3 3 3 1 0



Sample input:
4 4 1
2 1
1 3
3 2
3 4
4 1


Sample output:
0 1 0 1

Submission status: Accepted

Solution code:
import sys


def input():
    return sys.stdin.readline().strip()


sys.setrecursionlimit(10 ** 9)


class UnionFind:
    # 初期化
    def __init__(self, n_nodes):
        self.n_nodes = n_nodes
        # 親要素のノード番号を格納する.初めは全て親ノード.
        # self.parent[x] == x の時，そのノードは根.
        self.parent = [i for i in range(n_nodes)]
        # 木の高さを格納する．
        self.rank = [1] * n_nodes
        # 自分と同じグループの要素数を格納．親要素を参照するようにする
        self.size = [1] * n_nodes

    # 検索. 根を返す.
    def find(self, x):
        if self.parent[x] == x:
            return x
        else:
            # 一度調べた値は，根に繋ぎ直す.
            self.parent[x] = self.find(self.parent[x])
            return self.parent[x]

    # 併合.
    # 木の高さが低くなるように.
    # 親要素の書き換えは少ない方がいい
    def unite(self, x, y):
        # 根を探す．
        x = self.find(x)
        y = self.find(y)
        # 根が同じ場合はそのまま
        if x == y:
            return
        # 木の高さを比較し，低い方を高い方の根に貼る.
        if self.rank[x] > self.rank[y]:
            self.parent[y] = x
            self.size[x] += self.size[y]
        else:
            self.parent[x] = y
            self.size[y] += self.size[x]
            if self.rank[x] == self.rank[y]:
                self.rank[y] += 1

    # 同じ集合に属するか判定
    def check(self, x, y):
        return self.find(x) == self.find(y)

    # 同一グループに所属する要素数を返す
    def get_size(self, x):
        return self.size[self.find(x)]

    # 親要素のリストを返す
    def get_parent_list(self):
        return [i for i in range(self.n_nodes) if self.find(i) == i]

    # グループの数を返す
    def get_n_groups(self):
        return len(self.get_parent_list())

    # 同じグループに所属する要素の集合を返す
    def get_members(self, x):
        parent = self.find(x)
        return [i for i in range(self.n_nodes) if self.find(i) == parent]

    # 全ての根に対する，グループのメンバーを返す．
    def get_members_dict(self):
        return {par: self.get_members(par) for par in self.get_parent_list()}


MOD = 10 ** 9 + 7


def main():
    N, M, K = map(int, input().split())
    UF = UnionFind(N)
    friend = [0] * N
    block = [0] * N
    for _ in range(M):
        a, b = map(int, input().split())
        UF.unite(a - 1, b - 1)
        friend[a - 1] += 1
        friend[b - 1] += 1

    for _ in range(K):
        c, d = map(int, input().split())
        if UF.check(c - 1, d - 1):
            block[c - 1] += 1
            block[d - 1] += 1
    answer = []
    for i in range(N):
        answer.append(UF.get_size(i) - friend[i] - block[i] - 1)
    print(*answer, sep=" ")


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
class UnionFind():
    def __init__(self, n):
        self.n = n  # 要素の総数．
        self.parents = [-1] * n  # 各要素の親要素の番号を格納するリスト．要素がrootの場合は-(そのグループの要素数)を返す

    def find(self, x):
        """要素xが属するグループの根を返す"""
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        """要素xが属するグループと要素yが属するグループとを併合する"""
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        """要素xが属するグループの要素数を返す"""
        return -self.parents[self.find(x)]

    def same(self, x, y):
        """要素x, yが同じグループに属するかどうかを返す"""
        return self.find(x) == self.find(y)

    def members(self, x):
        """要素xが属するグループに属する要素をリストで返す"""
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        """全ての根の要素をリストで返す"""
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        """グループの数を返す"""
        return len(self.roots())

    def all_group_members(self):
        """{ルート要素: [そのグループの要素のリスト]} の辞書を返す"""
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

def main():
    N, M, K = map(int, input().split())
    cnt = [0] * N
    uf = UnionFind(N)

    for _ in range(M):
        A, B = map(lambda x: int(x)-1, input().split())
        cnt[A] += 1
        cnt[B] += 1
        uf.union(A, B)

    for _ in range(K):
        C, D = map(lambda x: int(x)-1, input().split())
        if uf.same(C, D):
            cnt[C] += 1
            cnt[D] += 1

    for i in range(N):
        print(uf.size(i) - cnt[i] - 1, end=" ")


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
import itertools
sys.setrecursionlimit(1000000000)
from heapq import heapify,heappop,heappush,heappushpop
import math
import collections
MOD = 10**9+7
class UnionFind():
    
    def __init__(self,n):
        self.n = n
        self.parents = [-1]*n #各要素の親要素の番号を格納するリスト
    
    #要素xが属するグループの根を返す
    def find(self,x):
        if self.parents[x]<0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]
    
    #要素xと要素yが属するグループを併合する   
    def union(self,x,y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return
        
        if self.parents[x]>self.parents[y]:
            x,y = y,x
        
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    #要素xが属するグループのサイズを返す
    def size(self,x):
        return -self.parents[self.find(x)]
    
    #要素x,yが同じグループかどうかを返す
    def same(self,x,y):
        return self.find(x) == self.find(y)
    
    #要素xと同じグループのメンバーを返す
    def members(self,x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]
    
    #すべての根の要素を返す
    def roots(self):
        return [i for i,x in enumerate(self.parents) if x<0]
    
    #グループの数を返す
    def group_count(self):
        return len(self.roots())
    
    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}
    
    def __str__(self):
        return "\n".join("{}: {}".format(r,self.members(r)) for r in self.roots())


n,m,k = map(int,input().split())
fb = [0]*n
uf = UnionFind(n)
for i in range(m):
    a,b = map(int,input().split())
    uf.union(a-1,b-1)
    fb[a-1] += 1
    fb[b-1] += 1
for i in range(k):
    c,d = map(int,input().split())
    if uf.same(c-1,d-1):
        fb[c-1] += 1
        fb[d-1] += 1
Ans = []
for i in range(n):
    ans = uf.size(i) - fb[i] - 1
    Ans.append(ans)
print(*Ans)

Submission status: Accepted

Solution code:
from sys import stdin, setrecursionlimit


class UnionFindTree:
    def __init__(self, n):
        self.parent = [-1] * n

    def find(self, x):
        p = self.parent
        while p[x] >= 0:
            x, p[x] = p[x], p[p[x]]
        return x

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        p = self.parent
        if x != y:
            if x > y:
                x, y = y, x
            p[x], p[y] = p[x] + p[y], x

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.parent[self.find(x)]


def main():
    input = stdin.buffer.readline
    n, m, k = map(int, input().split())

    f = UnionFindTree(n)

    f_or_b = [0] * n

    for _ in range(m):
        a, b = map(int, input().split())
        f.union(a - 1, b - 1)
        f_or_b[a - 1] += 1
        f_or_b[b - 1] += 1

    for _ in range(k):
        c, d = map(int, input().split())
        if f.same(c - 1, d - 1):
            f_or_b[c - 1] += 1
            f_or_b[d - 1] += 1

    print(*[f.size(i) - f_or_b[i] - 1 for i in range(n)])


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()

Submission status: Accepted

Solution code:
from sys import stdin, setrecursionlimit


class UnionFindTree:
    def __init__(self, n):
        self.parent = [-1] * n

    def find(self, x):
        p = self.parent
        while p[x] >= 0:
            x, p[x] = p[x], p[p[x]]
        return x

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        p = self.parent
        if x != y:
            if x > y:
                x, y = y, x
            p[x], p[y] = p[x] + p[y], x

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.parent[self.find(x)]


def main():
    n, m, k = map(int, stdin.readline().split())

    f = UnionFindTree(n)

    f_or_b = [0] * n

    for _ in range(m):
        a, b = map(int, stdin.readline().split())
        f.union(a - 1, b - 1)
        f_or_b[a - 1] += 1
        f_or_b[b - 1] += 1

    for _ in range(k):
        c, d = map(int, stdin.readline().split())
        if f.same(c - 1, d - 1):
            f_or_b[c - 1] += 1
            f_or_b[d - 1] += 1

    print(*[f.size(i) - f_or_b[i] - 1 for i in range(n)])


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()

Submission status: Accepted

Solution code:
from sys import stdin, setrecursionlimit


class UnionFindTree:
    def __init__(self, n):
        self.parent = [-1] * n

    def find(self, x):
        p = self.parent
        while p[x] >= 0:
            x, p[x] = p[x], p[p[x]]
        return x

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        p = self.parent
        if x != y:
            x, y = sorted([x, y])
            p[x], p[y] = p[x] + p[y], x

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.parent[self.find(x)]


def main():
    n, m, k = map(int, stdin.readline().split())

    f = UnionFindTree(n)

    f_or_b = [0] * n

    for _ in range(m):
        a, b = map(int, stdin.readline().split())
        f.union(a - 1, b - 1)
        f_or_b[a - 1] += 1
        f_or_b[b - 1] += 1

    for _ in range(k):
        c, d = map(int, stdin.readline().split())
        if f.same(c - 1, d - 1):
            f_or_b[c - 1] += 1
            f_or_b[d - 1] += 1

    print(*[f.size(i) - f_or_b[i] - 1 for i in range(n)])


if __name__ == "__main__":
    setrecursionlimit(10000)
    main()

Submission status: Accepted

Solution code:
import collections
import sys
n,m,k = map(int,sys.stdin.readline().split())
parent = range(n+1)
sizes = [1] * (n + 1)
hd = [1] * (n + 1) 

def f(parent, u):
	if parent[u] != u:  parent[u] = f(parent, parent[u])
	return parent[u]

while(m):
	m-=1
	a,b = map(int,sys.stdin.readline().split())
	pa,pb = f(parent, a), f(parent, b)
	hd[a] +=1
	hd[b] +=1

	if pa != pb:
		if sizes[pa] <= sizes[pb]: pa,pb = pb,pa
		parent[pb] = pa
		sizes[pa] += sizes[pb]
		
while(k):
	k-=1
	a,b= map(int,sys.stdin.readline().split())
	pa,pb = f(parent, a), f(parent,b)
	if (pa == pb):
		hd[a] += 1
		hd[b] += 1
for u in range(1,n+1):
	print str(sizes[f(parent,u)] - hd[u]) ,

Submission status: Accepted

Solution code:
import collections
import sys
n,m,k = map(int,sys.stdin.readline().split())
parent = range(0, n+1)
sizes = [1] * (n + 1)
hd = [1] * (n + 1) 

def f(parent, u):
	if parent[u] != u:  parent[u] = f(parent, parent[u])
	return parent[u]

for _ in range(m):
	a,b = map(int,sys.stdin.readline().split())
	pa,pb = f(parent, a), f(parent, b)
	hd[a] +=1
	hd[b] +=1

	if pa != pb:
		if sizes[pa] <= sizes[pb]: pa,pb = pb,pa
		parent[pb] = pa
		sizes[pa] += sizes[pb]
		
for _ in range(k):
	c,d = map(int,sys.stdin.readline().split())
	pc,pd = f(parent, c), f(parent, d)
	if (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - hd[u])  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections
import sys
n,m,k = map(int,sys.stdin.readline().split())
parent = range(0, n+1)
sizes = [1] * (n + 1)
hd = [1] * (n + 1) 

def f(parent, u):
	if parent[u] != u:  parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in [map(int,sys.stdin.readline().split()) for _ in range(m)]:

	pa,pb = f(parent, a), f(parent, b)
	hd[a] +=1
	hd[b] +=1

	if pa != pb:
		if sizes[pa] <= sizes[pb]: pa,pb = pb,pa
		parent[pb] = pa
		sizes[pa] += sizes[pb]
		

for c,d in [map(int,sys.stdin.readline().split()) for _ in range(k)]:
	pc,pd = f(parent, c), f(parent, d)
	if (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - hd[u])  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections
import sys
n,m,k = map(int,sys.stdin.readline().split())
parent = range(0, n+1)
sizes = [1] * (n + 1)
hd = [1] * (n + 1) 

def f(parent, u):
	if parent[u] != u:  parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in [map(int,sys.stdin.readline().split()) for _ in range(m)]:

	pa,pb = f(parent, a), f(parent, b)
	hd[a] +=1
	hd[b] +=1

	if pa != pb:
		if sizes[pa] >= sizes[pb]:
			parent[pb] = pa
			sizes[pa] += sizes[pb]
		else:
			parent[pa] = pb
			sizes[pb] += sizes[pa]

for c,d in [map(int,sys.stdin.readline().split()) for _ in range(k)]:
	pc,pd = f(parent, c), f(parent, d)
	if (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - hd[u])  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections

n,m,k = map(int,raw_input().split(' '))


parent = range(0, n+1)
sizes = [1] * (n + 1)
hd = [1] * (n + 1) 

def f(parent, u):
	if parent[u] != u:  parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in [map(int, raw_input().split(' ')) for _ in range(m)]:

	pa,pb = f(parent, a), f(parent, b)
	hd[a] +=1
	hd[b] +=1

	if pa != pb:
		if sizes[pa] >= sizes[pb]:
			parent[pb] = pa
			sizes[pa] += sizes[pb]
		else:
			parent[pa] = pb
			sizes[pb] += sizes[pa]

for c,d in [map(int, raw_input().split(' ')) for _ in range(k)]:
	pc,pd = f(parent, c), f(parent, d)
	if (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - hd[u])  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections

n,m,k = map(int,raw_input().split(' '))

friendships = [map(int, raw_input().split(' ')) for _ in range(m)]
disses = [map(int, raw_input().split(' ')) for _ in range(k)]

parent = [i for i in range(0, n+1)]
sizes = [1 for i in range(0, n+1)]
hd = [1 for i in range(0, n + 1)]


def f(parent, u):
	if parent[u] != u:  parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in friendships:

	pa,pb = f(parent, a), f(parent, b)
	hd[a] +=1
	hd[b] +=1

	if pa != pb:
		if sizes[pa] >= sizes[pb]:
			parent[pb] = pa
			sizes[pa] += sizes[pb]
		else:
			parent[pa] = pb
			sizes[pb] += sizes[pa]

for c,d in disses:
	pc,pd = f(parent, c), f(parent, d)
	if (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - hd[u])  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections

n,m,k = map(int,raw_input().split(' '))

friendships = [map(int, raw_input().split(' ')) for _ in range(m)]
disses = [map(int, raw_input().split(' ')) for _ in range(k)]

parent = [i for i in range(0, n+1)]
sizes = [1 for i in range(0, n+1)]

hd = collections.Counter()
adj = collections.defaultdict(set)

def f(parent, u):
	if parent[u] != u: 
		parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in friendships:

	pa,pb = f(parent, a), f(parent, b)
	
	adj[a].add(b)
	adj[b].add(a)

	if pa != pb:
		if sizes[pa] >= sizes[pb]:
			parent[pb] = pa
			sizes[pa] += sizes[pb]
		else:
			parent[pa] = pb
			sizes[pb] += sizes[pa]

for c,d in disses:
	pc,pd = f(parent, c), f(parent, d)
	if d not in adj[c] and (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - len(adj[u]) - hd[u] - 1)  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections

n,m,k = map(int,raw_input().split(' '))

friendships = [map(int, raw_input().split(' ')) for _ in range(m)]
disses = [map(int, raw_input().split(' ')) for _ in range(k)]

parent = {i:i for i in range(0, n+1)}
sizes = {i:1 for i in range(0, n+1)}

hd = collections.Counter()

adj = collections.defaultdict(set)

def f(parent, u):
	if parent[u] != u: 
		parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in friendships:

	pa,pb = f(parent, a), f(parent, b)
	
	adj[a].add(b)
	adj[b].add(a)

	if pa != pb:
		if sizes[pa] >= sizes[pb]:
			parent[pb] = pa
			sizes[pa] += sizes[pb]
		else:
			parent[pa] = pb
			sizes[pb] += sizes[pa]

for c,d in disses:
	pc,pd = f(parent, c), f(parent, d)
	if d not in adj[c] and (pc == pd):
		hd[c] += 1
		hd[d] += 1

print ' '.join([str(sizes[f(parent,u)] - len(adj[u]) - hd[u] - 1)  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
import collections

n,m,k = map(int,raw_input().split(' '))

friendships = [map(int, raw_input().split(' ')) for _ in range(m)]
disses = [map(int, raw_input().split(' ')) for _ in range(k)]

parent = {i:i for i in range(0, n+1)}
sizes = {i:1 for i in range(0, n+1)}

hd = collections.Counter()

adj = collections.defaultdict(set)

def f(parent, u):
	if parent[u] != u: 
		parent[u] = f(parent, parent[u])
	return parent[u]

for a,b in friendships:
	if a == b: continue

	pa,pb = f(parent, a), f(parent, b)
	
	adj[a].add(b)
	adj[b].add(a)

	if pa != pb:
		if sizes[pa] >= sizes[pb]:
			parent[pb] = pa
			sizes[pa] += sizes[pb]
		else:
			parent[pa] = pb
			sizes[pb] += sizes[pa]

for c,d in disses:
	pc,pd = f(parent, c), f(parent, d)
	if (pc == pd):
		hd[c] += 1
		hd[d] += 1
"""
hd[u] = k
u has k disses in its connected component
"""

print ' '.join([str(sizes[f(parent,u)] - len(adj[u]) - hd[u] - 1)  for u in range(1, n+1)])

Submission status: Accepted

Solution code:
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1]*n
    
    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x,y = y,x
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.parents[self.find(x)]

N, M, K = map(int, input().split())
friend = UnionFind(N+1)
nocount = [[] for _ in range(N+1)]
ans = [0]*N
for i in range(M):
  a, b = map(int, input().split())
  friend.union(a,b)
  nocount[a].append(b)
  nocount[b].append(a)
for i in range(K):
  a, b = map(int, input().split())
  nocount[a].append(b)
  nocount[b].append(a)
for i in range(1, N+1):
  ans[i-1] = friend.size(i) -1
  for j in nocount[i]:
    if friend.same(i,j):
      ans[i-1] -= 1
print(*ans)

Submission status: Accepted

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,M,K = inputIL()

friend = [[] for _ in range(N)]
friend_edges = []
for _ in range(M):
  a, b = inputIL()
  friend_edges.append((a-1, b-1))
for a, b in friend_edges:
  friend[a].append(b)
  friend[b].append(a)
  
block = [[] for _ in range(N)]
block_edges = []
for _ in range(K):
  a, b = inputIL()
  block_edges.append((a-1, b-1))
for a, b in block_edges:
  block[a].append(b)
  block[b].append(a)

  
cluster = [None for i in range(N)]
count = []

n = -1
for v in range(N):
  if cluster[v] == None:
    n += 1
    q = deque([v])
    cluster[v] = n
    c = 1
    while q:
      i = q.popleft()
      for j in friend[i]:
        if cluster[j] == None:
          cluster[j] = n
          c += 1
          q.append(j)
    count.append(c)

ans = [count[cluster[i]]-1 for i in range(N)]

for a, b in friend_edges:
  if cluster[a]==cluster[b]:
    ans[a] -= 1
    ans[b] -= 1

for a, b in block_edges:
  if cluster[a]==cluster[b]:
    ans[a] -= 1
    ans[b] -= 1
  

print(*ans,sep=" ")

Submission status: Accepted

Solution code:
import sys, bisect, math, itertools, heapq, collections
from operator import itemgetter
# a.sort(key=itemgetter(i)) # i番目要素でsort
from functools import lru_cache
# @lru_cache(maxsize=None)
sys.setrecursionlimit(10**8)
input = sys.stdin.readline
INF = float('inf')
mod = 10**9+7
eps = 10**-7
def inp():
    '''
    一つの整数
    '''
    return int(input())
def inpl():
    '''
    一行に複数の整数
    '''
    return list(map(int, input().split()))

class UnionFind():
    def __init__(self, n):
        """
        Parameters
        ----------
        n:int
            the number of node
        """
        self.par = [-1] * n # -self.par[i] means the tree size

    def find(self, x):
        """
        Parameters
        ----------
        x:int
            target node

        Return
        ----------
        res:int
            root node
        """
        if self.par[x] < 0:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.par[x] > self.par[y]: # lesser has many nodes
                x, y = y, x
            self.par[x] += self.par[y]
            self.par[y] = x

    def is_same(self, x, y):
        return self.find(x) == self.find(y)
    
    def size(self, x):
        '''
        Parameters
        ----------
        x:int
            target node
        
        Return
        ----------
        x:int
            size of  group  to which belongs
        '''
        return - self.par[self.find(x)]
        

n, m, k = inpl()
dame = collections.defaultdict(set)
uf = UnionFind(n)
ans=[0]*n
for i in range(m):
    a, b = inpl()
    a, b = a - 1, b - 1
    dame[a].add(b)
    dame[b].add(a)
    uf.union(a,b)
for i in range(k):
    c, d = inpl()
    c, d = c - 1, d - 1
    if uf.is_same(c,d):
        dame[c].add(d)
        dame[d].add(c)
for i in range(n):
    ans[i] = uf.size(i) - len(dame[i]) - 1
    # 同じグループに所属 - (友達+ブロック) - 自分
print(*ans)

'''

'''

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**5)

n,m,k=map(int,input().split())
fr=[0 for _ in range(n)]
frl=[[] for i in range(n)]
frlist=[]
for i in range(m):
    a,b=map(int,input().split())
    frl[a-1].append(b)
    frl[b-1].append(a)
    frlist.append([a,b])

treelist=[]
hitobito=set()

def saiki(c,tmpi):
    global hitobito
    global tmpset
    global trbl
    
    if frl[c-1] == []:
        hitobito.add(c)
        tmpset.add(c)
        trbl[c-1]=tmpi
    
    for tsugi in frl[c-1]:
        if not tsugi in hitobito:
            hitobito.add(tsugi)
            tmpset.add(tsugi)
            trbl[tsugi-1]=tmpi
            saiki(tsugi,tmpi)

index=0
trbl=[None for _ in range(n)]
for i in range(n):
    tmpset=set()
    saiki(i+1,index)
    if not tmpset == set():
        treelist.append(tmpset)
        index+=1

bl=[0 for _ in range(n)]
bll=[[] for i in range(n)]
bllist=[]
for i in range(k):
    a,b=map(int,input().split())
    bll[a-1].append(b)
    bll[b-1].append(a)
    bllist.append([a,b])

for fre in frlist:
    if trbl[fre[0]-1] == trbl[fre[1]-1]:
        fr[fre[0]-1]=fr[fre[0]-1]+1
        fr[fre[1]-1]=fr[fre[1]-1]+1

for blo in bllist:
    if trbl[blo[0]-1] == trbl[blo[1]-1]:
        bl[blo[0]-1]=bl[blo[0]-1]+1
        bl[blo[1]-1]=bl[blo[1]-1]+1

output=[]
for i in range(n):
    tmpsum=fr[i]+bl[i]
    output.extend([str(len(treelist[trbl[i]])-tmpsum-1)," "])

print("".join(output))

Submission status: Accepted

Solution code:
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]
    
    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

n,m,k=map(int,input().split())
uf = UnionFind(n)
friend=[0]*n
for i in range(m):
    a,b=map(int,input().split())
    a-=1
    b-=1
    friend[a]+=1
    friend[b]+=1
    uf.union(a,b)

block=[0]*n
for i in range(k):
    c,d=map(int,input().split())
    c-=1
    d-=1
    if uf.same(c,d):
        block[c]+=1
        block[d]+=1

ans=[0]*n
for i in range(n):
    ans[i]=uf.size(i)-friend[i]-block[i]-1

print(*ans)

Submission status: Accepted

Solution code:
N, M, K = map(int, input().split())
INF = 10**9

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


union_find = UnionFind(N)
friend_num_list = [0]*N
block_num_list = [0]*N

for _ in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    friend_num_list[a] += 1
    friend_num_list[b] += 1
    union_find.union(a, b)

for _ in range(K):
    c, d = map(int, input().split())
    c -= 1
    d -= 1
    if union_find.same(c, d):
        block_num_list[c] += 1
        block_num_list[d] += 1

ans_list = [0]*N
for i in range(N):
    ans = union_find.size(i) - friend_num_list[i] - block_num_list[i] - 1
    ans_list[i] = ans
print(*ans_list)

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
def main():
  n,m,k=map(int,input().split())
  ab=[list(map(int,input().split())) for _ in range(m)]
  cd=[list(map(int,input().split())) for _ in range(k)]
  gf=[[]for _ in range(n)]
  for a,b in ab:
    gf[a-1].append(b-1)
    gf[b-1].append(a-1)
  gb=[[]for _ in range(n)]
  for c,d in cd:
    gb[c-1].append(d-1)
    gb[d-1].append(c-1)
  seen=[0]*n
  ans=[0]*n
  for i in range(n):
    c=set([i])
    if seen[i]==0:
      todo=[i]
      while todo:
        e=todo.pop()
        l=gf[e]
        for li in l:
          if seen[li]==0:
            todo.append(li)
            seen[li]=1
            c.add(li)
      base=len(c)-1
      for ci in c:
        ans[ci]=base
        for fb in gb[ci]+gf[ci]:
          if fb in c:
            ans[ci]-=1
  print(' '.join(map(str,ans)))
if __name__=='__main__':
  main()