Problem:


  MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Connected Components

  Write a program which reads relations in a SNS (Social Network Service), and judges that given pairs of users are reachable each other through the network.

Input

  In the first line, two integer $n$ and $m$ are given. $n$ is the number of users in the SNS and $m$ is the number of relations in the SNS. The users in the SNS are identified by IDs $0, 1, ..., n-1$.

  In the following $m$ lines, the relations are given. Each relation is given by two integers $s$ and $t$ that represents $s$ and $t$ are friends (and reachable each other).

  In the next line, the number of queries $q$ is given. In the following $q$ lines, $q$ queries are given respectively. Each query consists of two integers $s$ and $t$ separated by a space character.

Output

  For each query, print "yes" if $t$ is reachable from $s$ through the social network, "no" otherwise.

Constraints

$2 \leq n \leq 100,000$

$0 \leq m \leq 100,000$

$1 \leq q \leq 10,000$

Sample Input

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

Sample Output

yes
yes
no



Sample input:
10 9
0 1
0 2
3 4
5 7
5 6
6 7
6 8
7 8
8 9
3
0 1
5 9
1 3


Sample output:
yes
yes
no

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(200000)

def dfs(v):
    global node_chk
    global edge_chk
    global B
    global connect
    global value

    node_chk[v] = 1
    connect[v] = value
    for x in B[v]:
        if(node_chk[x] == 0):
                dfs(x)



n,m = map(int,input().split())
B = [[]for i in range(n)] # 隣接リスト
edge_chk = [[]for i in range(n)]
node_chk = [0 for i in range(n)]
connect = [0 for i in range(n)]
value = 0

for i in range(m):
    A = list(map(int,input().split()))
    B[A[0]].append(A[1])
    B[A[1]].append(A[0])
    edge_chk[A[0]].append(0)
    edge_chk[A[1]].append(0)

for i in range(n):
    if(node_chk[i] == 1):
        continue
    dfs(i)
    value += 1


q = int(input())
for i in range(q):
    start,target = map(int,input().split())
    if(connect[start] == connect[target]):
        print("yes")
    else:
        print("no")

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(200000)

def dfs(v):
    global node_chk
    global B
    global connect
    global value

    node_chk[v] = 1
    connect[v] = value
    for x in B[v]:
        if(node_chk[x] == 0):
                dfs(x)



n,m = map(int,input().split())
B = [[]for i in range(n)] # 隣接リスト
node_chk = [0 for i in range(n)]
connect = [0 for i in range(n)]
value = 0

for i in range(m):
    A = list(map(int,input().split()))
    B[A[0]].append(A[1])
    B[A[1]].append(A[0])

for i in range(n):
    if(node_chk[i] == 1):
        continue
    dfs(i)
    value += 1


q = int(input())
for i in range(q):
    start,target = map(int,input().split())
    if(connect[start] == connect[target]):
        print("yes")
    else:
        print("no")

Submission status: Accepted

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

V, E = map(int, input().split())
G = {i: deque([]) for i in range(V)}
for _ in range(E):
    v1, v2 = map(int, input().split())
    G[v1].append(v2)
    G[v2].append(v1)


seen = [0]*(V)
stack = []
color = {v: -1 for v in range(V)}

def dfs(j, col):
    global time
    if seen[j]:
        return
    seen[j] = 1
    stack.append(j)
    color[j] = col
    while stack:
        s = stack[-1]
        if not G[s]:
            stack.pop()
            continue
        g_NO  = G[s].popleft()
        if seen[g_NO]:
            continue
        color[g_NO] = col
        seen[g_NO] = 1
        stack.append(g_NO)
    
c = 0
for start in range(V):
    if seen[start]:
        continue
    dfs(start, c)
    c += 1


q = int(input())
for _ in range(q):
    s, t = map(int, input().split())
    if color[s] != -1 and color[t] != -1 and color[s] == color[t]:
        print("yes")
    else:
        print("no")

Submission status: Accepted

Solution code:
from collections import defaultdict
import sys
sys.setrecursionlimit(1 << 25)  # 再起上限引き上げ

G = defaultdict(lambda: [])

#load data
N,M = map(int,input().split())
color = {key: None for key in range(N)}
#graphをdefaultdictで保持することにする
for _ in range(M):
    s,t = map(int,input().split())
    G[s].append(t)
    G[t].append(s)

#隣接リストを基にたどり着ける友達をグループ化する。
def dfs(node:int, co:int):
    #終了条件、既に訪問済みなら訪問しない
    if color[node] is not None:
        return
    #処理
    color[node] = co
    for n in G[node]:
        dfs(n,co)

    return

#全てのnodeを開始点としてdfsで色分けしてみる
c = 1
for node in G.keys():
    dfs(node,c)
    c += 1

#問題への解答
Q = int(input())
for _ in range(Q):
    s,t = map(int,input().split())
    if (color[s] is not None) and (color[t] is not None) and (color[s] == color[t]):
        print('yes')
    else:
        print('no')

Submission status: Accepted

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

    # retrun the root of element 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]

    # unite the group include element x and group include element y
    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.parents[y] += self.parents[x]
            self.parents[x] = y
        else:
            self.parents[x] += self.parents[y]
            self.parents[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # get size of the gourp which element x belongs
    def get_size(self, x):
        return -self.parents[self.find(x)]

    # check if element x and element y is same group
    def same(self, x, y):
        return self.find(x) == self.find(y)


n, m = [int(i) for i in input().split()]
union = UnionFind(n)
for _ in range(m):
    s, t = [int(i) for i in input().split()]
    union.unite(s, t)

q = int(input())
for _ in range(q):
    s, t = [int(i) for i in input().split()]
    if union.same(s, t):
        print("yes")
    else:
        print("no")

Submission status: Accepted

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

from collections import deque, defaultdict
from copy import deepcopy

MAX = 100000
NIL = -1

# Gはdictで管理する、valueはdeque
G = defaultdict(lambda: deque())
color = [NIL]*MAX

def dfs(r, c):
    S = deque()
    S.append(r)
    color[r] = c
    while S:
        u = S.popleft()
        for v in G[u]:  # Gのvalueはdequeなので、それをvに一つずつ入れていく
            if color[v] == NIL:
                color[v] = c
                S.append(v)

def assign_color():
    id = 1
    for u in range(n):
        if color[u] == NIL:
            dfs(u, id)
            id += 1

n, m = map(int, input().split())

for _ in range(m):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

assign_color()

q = int(input())
for _ in range(q):
    s, t = map(int, input().split())
    if color[s] == color[t]:
        print('yes')
    else:
        print('no')

Submission status: Accepted

Solution code:
import sys, os, math, bisect, itertools, collections, heapq, queue, copy, array

# from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall
# from decimal import Decimal
# from collections import defaultdict, deque

sys.setrecursionlimit(10000000)

ii = lambda: int(sys.stdin.buffer.readline().rstrip())
il = lambda: list(map(int, sys.stdin.buffer.readline().split()))
fl = lambda: list(map(float, sys.stdin.buffer.readline().split()))
iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)]

iss = lambda: sys.stdin.buffer.readline().decode().rstrip()
sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split()))
isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)]

lcm = lambda x, y: (x * y) // math.gcd(x, y)

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


class UnionFind:
    def __init__(self, N):
        self.tree = list(range(N))

    def root(self, N):
        if self.tree[N] == N:
            return N
        else:
            self.tree[N] = self.root(self.tree[N])
            return self.tree[N]

    def same(self, x, y):
        return self.root(self.tree[x]) == self.root(self.tree[y])

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        else:
            self.tree[x] = y


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    N, M = il()
    uf = UnionFind(N)
    for _ in range(M):
        s, t = il()
        uf.unite(s, t)

    Q = ii()
    for _ in range(Q):
        s, t = il()
        if uf.same(s, t):
            print('yes')
        else:
            print('no')


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
from collections import deque, defaultdict

sys.setrecursionlimit(10**7)

n, m = map(int, input().split())

G = defaultdict(lambda: deque())
color = [-1]*n

for _ in range(m):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

def dfs(node, co):
    if color[node] != -1:
        return

    color[node] = co

    for n in G[node]:
        dfs(n, co)
        

c = 1
for node in G.keys():
    dfs(node, c)
    c += 1


q = int(input())
for _ in range(q):
    s, t = map(int, input().split())
    if color[s] != -1 and color[t] != -1 and color[s] == color[t]:
        print('yes')
    else:
        print('no')

Submission status: Accepted

Solution code:
from collections import deque
n,m = map(int,input().split())
data = [[] for _ in range(n)]
for _ in range(m):
    a,b = map(int,input().split())
    data[a].append(b)
    data[b].append(a)
visited = [0]*n
kind = [-1]*n
dq = deque([])
for i in range(n):
    if not visited[i]:
        dq.append(i)
        while dq:
            p = dq.pop()
            if not visited[p]:
                kind[p] = i
                visited[p] = 1
                for j in data[p]:
                    dq.append(j)
q = int(input())
for _ in range(q):
    a,b = map(int,input().split())
    print("yes" if kind[a]==kind[b] else "no")

Submission status: Accepted

Solution code:
from collections import defaultdict
import sys
sys.setrecursionlimit(1 << 25)

G = defaultdict(lambda: [])
n, m = map(int, input().split())
color = {key: None for key in range(n)}

for _ in range(m):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

# 離接リストをもとに、たどり着ける友達関係をグループ化する #(union findが使える気もするけどここではDFSで領域を探索していく)


def dfs(node: int, co: int):
    if color[node] is not None:
        return
    color[node] = co

    for no in G[node]:
        dfs(no, co)
    return


# すべてのnodeを開始点としてdfsで領域わけしてみる
c = 1
for node in G.keys():
    dfs(node, c)
    c += 1

Q = int(input())
for _ in range(Q):
    s, t = list(map(int, input().split()))
    if color[s] and color[t] and color[s] == color[t]:
        print('yes')
    else:
        print('no')

Submission status: Accepted

Solution code:
import sys, collections
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = 10**10
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    n, m = LI()
    edge = [[] for _ in range(n)]
    cc = [-1]*n

    for _ in range(m):
        s, t = LI()
        edge[s].append(t)
        edge[t].append(s)

    ccid = 0
    for i in range(n):
        if cc[i]==-1:
            stk = [i]
            cc[i] = ccid
            while stk:
                c = stk.pop()
                for n in edge[c]:
                    if cc[n]==-1:
                        stk.append(n)
                        cc[n] = ccid

            ccid += 1

    q = I()
    for _ in range(q):
        s, t = LI()
        if cc[s] == cc[t]:
            print('yes')
        else:
            print('no')

if __name__ == '__main__':
    resolve()

Submission status: Accepted

Solution code:
from collections import deque

UNVISITED=0
ENTERED=1
VISITED=2

def nextNL(u, nList, state):
    l=nList[u]
    for i in l:
        if(state[i]==UNVISITED):
            return i
    return -1

def dfs(s,t,nList,state, color,icol):

    S=[]

    S.append(s)
    state[s]=ENTERED
    color[s]=icol
    while(len(S)>0):
        current=S[-1]
        next=nextNL(current, nList, state)
        if next!=-1:
            S.append(next)
            state[next]=ENTERED
            color[next]=icol
        else:
            state[S.pop()]=VISITED

    return color[s]==color[t]

def main():

    n,m=list(map(int,input().split()))
    nList=[]
    for _ in range(n):
        nList.append([])

    for _ in range(m):
        s,t=list(map(int,input().split()))
        nList[s].append(t)
        nList[t].append(s)
    
    state=[UNVISITED]*n

    q=int(input())

    icol=-1
    color=[icol]*n
    for _ in range(q):
        s,t=list(map(int,input().split()))
        if(color[s] == -1) and (color[t] == -1):
            icol+=1
            res=dfs(s,t,nList,state,color,icol)
            if(res==True):
                print('yes')
            else:
                print('no')
        elif (color[s]==-1) or (color[t]==-1):
            print('no')
        elif (color[s] == color[t]):
            print('yes')
        else:
            print('no')
    
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
import copy

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())


if __name__  == "__main__":
    input = sys.stdin.readline
    n,m = map(int,input().split())
    UF = UnionFind(n)
    for i in range(m):
        a,b = map(int,input().split())
        UF.union(a,b)
    q = int(input())
    for i in range(q):
        c,d = map(int,input().split())
        if UF.same(c,d):
            print("yes")
        else:
            print("no")

Submission status: Accepted

Solution code:
#Union Find

#xの根を求める
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合
def unite(x,y):
    x = find(x)
    y = find(y)
    
    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定
def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数
def size(x):
    return -par[find(x)]

#初期化
#根なら-size,子なら親の頂点
n,m = map(int,input().split())
par = [-1]*n
for i in range(m):
  x,y = map(int,input().split())
  unite(x,y)

k = int(input())
for i in range(k):
  a,b = map(int,input().split())
  if same(a,b):
    print("yes")
  else:
    print("no")

Submission status: Accepted

Solution code:
import sys
import copy
from collections import deque
sys.setrecursionlimit(20000)
N,relation=input().split()
N,relation=int(N),int(relation)
g = [set() for i in range(N)]

def BFS(a,b):
    bfs = deque([a])
    grp={a:None}
    grp2={a}
    while bfs:
        i=bfs.popleft()
        for j in g[i]:
            if j not in grp2:
                grp[j]=a
                grp2.add(j)
                bfs.append(j)
    return grp,grp2


for i in range(relation):
    kari=[]
    j,k=list(map(int,input().split()))
    g[j].add(k)
    g[k].add(j)
group=[]
tansaku=int(input())
for i in range(tansaku):
    a,b=list(map(int,input().split()))
    for k in range(len(group)):
        if a in group[k] and b in group[k]:
            print("yes")
            break
        elif a in group[k]:
            print("no")
            break
    else:
        grp,grp2=(BFS(a,b))
        grp=set(grp.keys())
        if b in grp:
            print("yes")
        else:print("no")
        group.append(grp)

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 in range(self.n) if self.parents[i] < 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 = map(int,input().split())
tree = UnionFind(n)
for _ in range(m):
    a,b = map(int,input().split())
    tree.union(a,b)

q = int(input())
for i in range(q):
    a,b = map(int,input().split())
    if tree.same(a,b):
        print("yes")
    else:
        print("no")

Submission status: Accepted

Solution code:
n, m = map(int, input().split())

# 隣接リストの雛形
D = dict()
for i in range(n):
    D[i] = []

# グラフを入力
for _ in range(m):
    s, t = map(int, input().split())
    D[s].append(t)
    D[t].append(s)

group = [-1]*n
cnt = 0
for i in range(n):
    if group[i] == -1:
        group[i] = cnt
        stack = [i]
        while stack:
            v = stack.pop()
            for c in D[v]:
                if group[c] == -1:
                    group[c] = cnt
                    stack.append(c)
        cnt += 1

q = int(input())
for _ in range(q):
    s, t = map(int, input().split())
    print('yes' if group[s] == group[t] else 'no')

Submission status: Accepted

Solution code:
import queue

N, M = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(M):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)

group = [0] * N
group_id = 1
que = queue.Queue()

for i in range(N):
    if group[i] != 0:
        continue
    group[i] = group_id
    que.put(G[i])
    while not que.empty():
        q = que.get()
        for j in q:
            if group[j] == 0:
                que.put(G[j])
                group[j] = group_id
    group_id += 1

Q = int(input())
for _ in range(Q):
    s, t = map(int, input().split())
    if group[s] == group[t]:
        print('yes')
    else:
        print('no')

Submission status: Accepted

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

from collections import deque, defaultdict
from copy import deepcopy

MAX = 100000
NIL = -1

#グラフGはdictで管理する
G = defaultdict(lambda:deque())
color = [NIL]*MAX

#頂点r,探索ごとに異なる数cによって深さ優先探索をする関数
#つながっている部分は全て色が同じになる
def dfs(r, c):
    S = deque()
    S.append(r) 
    color[r] = c
    while S: #Sが存在する間以下の処理を実行
        u = S.popleft()
        for v in G[u]:#Gのvalueはqueueとなっている
            if color[v] == NIL:#色がない場合のみ以下の操作を行う
                color[v] = c
                S.append(v) #深さを深くして次の頂点を探す準備をする

def make_color():
    id = 1
    for u in range(n):
        if color[u] == NIL:
            dfs(u, id) #色を塗る
            id += 1 #色を変える
        
    
    
n, m = map(int, input().split())

for _ in range(m):
    s, t = map(int, input().split())
    G[s].append(t)
    G[t].append(s)
    

make_color()

q = int(input())
for _ in range(q):
    s, t = map(int, input().split())
    if color[s] == color[t]:
        print('yes')
    else:
        print('no')

Submission status: Accepted

Solution code:
from collections import deque

def connected_components(U, C):
    no = 1

    for i in range(len(U)):
        if C[i] == None:
            depth_first_serch(U, C, i, no)
            no += 1

def depth_first_serch(U, C, r, no):
    S = list()
    S.append(r)

    while len(S) != 0:
        current = S[-1]
        
        if len(U[current]) != 0:
            v = U[current].popleft()
            if C[v] == None:
                C[v] = no
                S.append(v)
        else:
            C[current] = no
            S.pop()

def Main():
    N, M = map(int, input().split())
    Users = [deque() for n in range(N)]
    Color = [None for n in range(N)]

    for m in range(M):
        s, t = map(int, input().split())
        Users[s].append(t)
        Users[t].append(s)

    connected_components(Users, Color)

    Q = int(input())

    for q in range(Q):
        s, t = map(int, input().split())
        if Color[s] == Color[t]:
            print("yes")
        else:
            print("no")

Main()

Submission status: Accepted

Solution code:
from collections import deque
n,m = map(int,input().split())
G = [[] for _ in range(n)]
for i in range(m):
    s,t = map(int,input().split())
    s -= 1
    t -= 1
    G[s].append(t)
    G[t].append(s)

uni = [-1]*n
stk = deque()
def dfs(u,c):
    stk.append(u)
    while stk:
        u = stk.pop()
        uni[u] = c
        for v in G[u]:
            if uni[v] != -1: continue
            stk.append(v)

c = 0
for i in range(n):
    if uni[i] == -1:
        dfs(i,c)
        c += 1

q = int(input())
ans = ["no"]*q
for i in range(q):
    s,t = map(int,input().split())
    s -= 1
    t -= 1
    if uni[s] == uni[t]: ans[i] = "yes"

print("\n".join(ans))

Submission status: Accepted

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

        def root(self, x):
            if self.d[x] < 0:
                return x
            self.d[x] = self.root(self.d[x])
            return self.d[x]

        def unite(self, x, y):
            x, y = self.root(x), self.root(y)
            if x == y:
                return False
            if x > y:
                x, y = y, x
            self.d[x] += self.d[y]
            self.d[y] = x
            return True

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

    raw = tuple(map(int, open(0).read().split()))
    n, m = raw[:2]
    uf = UnionFind(n)
    [uf.unite(a, b) for a, b in zip(*[iter(raw[2:2*m+2])]*2)]

    [print('yes' if uf.same(a, b) else 'no') for a, b in zip(*[iter(raw[2*m+3:])]*2)]

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
class UnionFind:
    def __init__(self,n):
        self.n = n
        self.p = [i for i in range(n)]
        self.rank = [0]*n

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

    def root(self,x):
        if x!=self.p[x]:self.p[x] = self.root(self.p[x])
        return self.p[x]

    def unite(self,x,y):
        x = self.root(x)
        y = self.root(y)
        if self.rank[y]<self.rank[x]:
            self.p[y] = x
        else:
            self.p[x] = y
            if self.rank[y]==self.rank[x]:
                self.rank[y]+=1

def main():
    n,m = map(int,input().split())
    UF = UnionFind(n)
    for _ in range(m):
        a,b = map(int,input().split())
        UF.unite(a,b)
    q = int(input())
    for _ in range(q):
        a,b = map(int,input().split())
        if UF.same(a,b):print ('yes')
        else           :print ('no')


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(15000)
n,m = map(int,sys.stdin.readline().split())
g = list(range(n))
def find(x):
  while g[x] != x:
    x = g[x]
    g[x] = g[g[x]]
  return x
def union(s,t):
  sp = find(s)
  tp = find(t)
  if sp == tp:
    pass
  elif sp < tp:
    g[sp] = tp
  else:
    g[tp] = sp
for i in range(m):
  s,t = map(int,sys.stdin.readline().split())
  union(s,t)

q = int(sys.stdin.readline())
for i in range(q):
  s,t = map(int,sys.stdin.readline().split())
  if find(s) == find(t):
    print("yes")
  else:
    print("no")

Submission status: Accepted

Solution code:
from enum import Enum
import sys
import math

BIG_NUM = 2000000000
MOD = 1000000007
EPS = 0.000000001


V,E = map(int,input().split())

boss = [i for i in range(V)]
height = [0 for i in range(V)]

def get_boss(index):
    if index == boss[index]:
        return index
    else:
        boss[index] = get_boss(boss[index])
        return boss[index]


def is_same_group(a,b):
    return get_boss(a) == get_boss(b)

def unite(x,y):
    boss_x = get_boss(x)
    boss_y = get_boss(y)

    if boss_x == boss_y:
        return

    if height[x] > height[y]:

        boss[boss_y] = boss_x

    elif height[x] < height[y]:

        boss[boss_x] = boss_y

    else:
        boss[boss_y] = boss_x
        height[x] += 1


for loop in range(E):
    A,B = map(int,input().split())
    unite(A,B)

num_query = int(input())

for loop in range(num_query):
    A,B = map(int,input().split())
    if is_same_group(A,B) == True:
        print("yes")
    else:
        print("no")

Submission status: Accepted

Solution code:
import sys
input = lambda: sys.stdin.readline().rstrip()
sys.setrecursionlimit(10**6)
def dfs(g,v,z):
    if vis[v]!=0: return
    else:
        vis[v]=z
        for p in g[v]:
            dfs(g,p,z)
n,m=map(int,input().split())
g=[[] for i in range(n)]
for i in range(m):
    x,y=map(int,input().split())
    g[x].append(y)
    g[y].append(x)
z=0 ; vis=[0]*n
for i in range(n):
    if vis[i]==0:
        z+=1
        dfs(g,i,z)
q=int(input())
for i in range(q):
    x,y=map(int,input().split())
    if vis[x]==vis[y]: print('yes')
    else: print('no')

Submission status: Accepted

Solution code:
n,m = map(int,input().split())
Rel = [tuple(map(int,input().split())) for _ in range(m)]
q = int(input())
Que = [tuple(map(int,input().split())) for _ in range(q)]

class UF:
    def __init__(self):
        self.roots = [i for i in range(n)]
        self.rank = [1 for _ in range(n)]

    def same(self,a,b):
        if self.find(a) == self.find(b):
            return True
        else:
            return False

    def find(self,a):
        if self.roots[a] == a:
            return a
        else:
            self.roots[a] = self.find(self.roots[a])
            return self.roots[a]

    def union(self,a,b):
        a,b = self.find(a),self.find(b)
        if a != b:
            if self.rank[a] >= self.rank[b]:
                self.roots[b] = a
                if self.rank[a] == self.rank[b]:
                    self.rank[b] += 1
            else:
                self.roots[a] = b

uf = UF()

for i in range(m):
    uf.union(Rel[i][0],Rel[i][1])

for i in range(q):
    if uf.same(Que[i][0],Que[i][1]):
        print("yes")
    else:
        print("no")

Submission status: Accepted

Solution code:
import sys
# sys.stdin = open('input.txt')

def dfs(r, c):
    S = []
    S.append(r)
    color[r] = c
    while len(S) > 0:
        u = S.pop()
        for v in G[u]:
            if color[v] is None:
                color[v] = c
                S.append(v)

def assignColors():
    colorId = 0
    for i in range(n):
        if color[i] is None:
            dfs(i, colorId)
            colorId += 1

n, m  = map(int, input().split())
G = [[] for _ in range(n)]
color = [None] * n

for i in range(m):
    s, t = map(int, input().split())
    # Doubly link
    G[s].append(t)
    G[t].append(s)

assignColors()

q = int(input())
for i in range(q):
    s, t = map(int, input().split())
    if color[s] is not None and color[s] == color[t]:
        print('yes')
    else:
        print('no')

Submission status: Accepted

Solution code:
if __name__ == '__main__':
    from sys import stdin
    input = stdin.readline

    from collections import deque, defaultdict
    from copy import deepcopy

    MAX = 100000
    NIL = -1

    # Gはdictで管理する、valueはdeque
    G = defaultdict(lambda: deque())
    color = [NIL]*MAX

    def dfs(r, c):
        S = deque()
        S.append(r)
        color[r] = c
        while S:
            u = S.popleft()
            for v in G[u]:  # Gのvalueはdequeなので、それをvに一つずつ入れていく
                if color[v] == NIL:
                    color[v] = c
                    S.append(v)

    def assign_color():
        id = 1
        for u in range(n):
            if color[u] == NIL:
                dfs(u, id)
                id += 1

    n, m = map(int, input().split())

    for _ in range(m):
        s, t = map(int, input().split())
        G[s].append(t)
        G[t].append(s)

    assign_color()

    q = int(input())
    for _ in range(q):
        s, t = map(int, input().split())
        if color[s] == color[t]:
            print('yes')
        else:
            print('no')

Submission status: Accepted

Solution code:
from collections import deque

def bfs(graph, start):
    visited = {start: None}
    unvisited = deque()
    unvisited.append(start)
    while unvisited:
        now = unvisited.popleft()
        for next in graph[now]:
            if not (next in visited):
                unvisited.append(next)
                visited[next] = now
    return  visited                                

n, m = map(int, input().split())
g = [set() for _ in range(n)]
group = []

for i in range(m):
    a, b = map(int, input().split())
    g[a].add(b)
    g[b].add(a)

q = int(input())

for i in range(q):
    s, t = map(int, input().split())
    for j in range(len(group)):
        if s in group[j] and t in group[j]:
            print('yes')
            break
        elif s in group[j]:
            print('no')
            break
    
    else:
        group_tmp = set(bfs(g, s).keys())
        if t in group_tmp:
            print('yes')
        else:
            print('no')
        group.append(group_tmp)

Submission status: Accepted

Solution code:
n_people, n_relationship = list(map(int, input().split()))
adj_list = [[] for _ in range(n_people)]
for i in range(n_relationship):
  p, target = list(map(int, input().split()))
  adj_list[p].append(target)
  adj_list[target].append(p)


group = [-1] * n_people
cnt = 0
for i in range(n_people):
  if group[i] == -1:
    group[i] = cnt
    stack = [i]
    while stack:
      at = stack.pop()
      for to in adj_list[at]:
        if group[to] == -1:
          group[to] = cnt
          stack.append(to)

    cnt += 1

for _ in range(int(input())):
    s, t = map(int, input().split())
    print('yes' if group[s] == group[t] else 'no')