Problem: 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?

Submission attempts (in order):
import bisect


class UnionFind():
    
    def __init__(self, n):
        self.n = next
        self.parent = [-1 for i in range(n)]
    
    def find(self, x):
        if self.parent[x] < 0:
            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 False
        else:
            if self.parent[x] > self.parent[y]:
                x, y = y, x
            self.parent[x] += self.parent[y]
            self.parent[y] = x
            return True
    
    def same(self, x, y):
        return self.find(x) == self.find(y)
    
    def size(self, x):
        return -self.parent[self.find(x)]
    
    def __str__(self):
        return str(self.parent)



def read():
    N, M, K = list(map(int, input().strip().split()))
    uf = UnionFind(N)
    friends = [list() for i in range(N+1)]
    blocked = [list() for i in range(N+1)]
    for i in range(M):
        a, b = list(map(int, input().strip().split()))
        friends[a].append(b)
        friends[b].append(a)
        uf.unite(a-1, b-1)
    for i in range(K):
        c, d = list(map(int, input().strip().split()))
        blocked[c].append(d)
        blocked[d].append(c)
    for i in range(N+1):
        friends[i] = sorted(friends[i])
        blocked[i] = sorted(blocked[i])
    return N, M, K, friends, blocked, uf


def solve(N, M, K, friends, blocked, uf):
    n_friendships = [0 for i in range(N)]
    for i in range(N):
        for j in friends[i]:
            bi = bisect.bisect_left(blocked[i+1], j+1)
            is_blocked = bi < len(blocked[i+1]) and blocked[i+1][bi] == j+1
            if not is_blocked:
                n_friendships[i] += 1
    return ' '.join(map(str, n_friendships))


if __name__ == '__main__':
    inputs = read()
    print("{}".format(solve(*inputs)))


import bisect


class UnionFind():
    
    def __init__(self, n):
        self.n = next
        self.parent = [-1 for i in range(n)]
    
    def find(self, x):
        if self.parent[x] < 0:
            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 False
        else:
            if self.parent[x] > self.parent[y]:
                x, y = y, x
            self.parent[x] += self.parent[y]
            self.parent[y] = x
            return True
    
    def same(self, x, y):
        return self.find(x) == self.find(y)
    
    def size(self, x):
        return -self.parent[self.find(x)]
    
    def __str__(self):
        return str(self.parent)



def read():
    N, M, K = list(map(int, input().strip().split()))
    uf = UnionFind(N)
    friends = [list() for i in range(N+1)]
    blocked = [list() for i in range(N+1)]
    for i in range(M):
        a, b = list(map(int, input().strip().split()))
        friends[a].append(b)
        friends[b].append(a)
        uf.unite(a-1, b-1)
    for i in range(K):
        c, d = list(map(int, input().strip().split()))
        blocked[c].append(d)
        blocked[d].append(c)
    return N, M, K, friends, blocked, uf


def solve(N, M, K, friends, blocked, uf):
    n_friendships = [0 for i in range(N)]
    for i in range(1, N+1):
        n = uf.size(i-1)
        m = len(friends[i])
        k = 0
        for b in blocked[i]:
            if uf.same(i-1, b-1):
                k += 1
        n_friendships[i-1] = n-1-m-k
    return ' '.join(map(str, n_friendships))


if __name__ == '__main__':
    inputs = read()
    print("{}".format(solve(*inputs)))


Verdicts: Wrong Answer

Accepted