Problem:


Score : 500 points

Problem Statement

There are N cards placed face down in a row. On each card, an integer 1 or 2 is written.

Let A_i be the integer written on the i-th card.

Your objective is to guess A_1, A_2, ..., A_N correctly.

You know the following facts:

For each i = 1, 2, ..., M, the value A_{X_i} + A_{Y_i} + Z_i is an even number.

You are a magician and can use the following magic any number of times:

Magic: Choose one card and know the integer A_i written on it. The cost of using this magic is 1.

What is the minimum cost required to determine all of A_1, A_2, ..., A_N?

It is guaranteed that there is no contradiction in given input.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq X_i < Y_i \leq N

1 \leq Z_i \leq 100

The pairs (X_i, Y_i) are distinct.

There is no contradiction in input. (That is, there exist integers A_1, A_2, ..., A_N that satisfy the conditions.)

Input

Input is given from Standard Input in the following format:

N M
X_1 Y_1 Z_1
X_2 Y_2 Z_2
\vdots
X_M Y_M Z_M

Output

Print the minimum total cost required to determine all of A_1, A_2, ..., A_N.

Sample Input 1

3 1
1 2 1

Sample Output 1

2

You can determine all of A_1, A_2, A_3 by using the magic for the first and third cards.

Sample Input 2

6 5
1 2 1
2 3 2
1 3 3
4 5 4
5 6 5

Sample Output 2

2

Sample Input 3

100000 1
1 100000 100

Sample Output 3

99999



Sample input:
3 1
1 2 1


Sample output:
2

Submission status: Accepted

Solution code:
class UnionFind:
    def __init__(self, max_size):
        self.parent = [i for i in range(max_size+1)]
        self.depth = [0 for _ in range(max_size+1)]
        self.cnt = [1 for i in range(max_size+1)]
    def find(self, x):
        t = x
        while t!=self.parent[t]:
            t = self.parent[t]
        self.parent[x]=t
        return t
    
    def unite(self,x,y):
        x = self.find(x)
        y = self.find(y)
        if x==y:
            return
        elif self.depth[x]<self.depth[y]:
            self.parent[x] = y
            self.cnt[y] += self.cnt[x]
        else:
            self.parent[y] = x
            self.cnt[x]+=self.cnt[y]
            if self.depth[x]==self.depth[y]:
                self.depth[x]+=1
    def same(self, x, y):
        return self.find(x)==self.find(y)
    def size(self,x):
        return self.cnt[self.find(x)]

n,m = map(int,input().split())
utree = UnionFind(n+10)
for _ in range(m):
    x,y,z = map(int,input().split())
    utree.unite(x,y)
s = {utree.find(i) for i in range(1,n+1)}
print(len(s))

Submission status: Accepted

Solution code:
class UnionFind:
    def __init__(self, max_size):
        self.parent = [i for i in range(max_size+1)]
        self.depth = [0 for _ in range(max_size+1)]
        self.cnt = [1 for i in range(max_size+1)]
    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
        elif self.depth[x]<self.depth[y]:
            self.parent[x] = y
            self.cnt[y] += self.cnt[x]
        else:
            self.parent[y] = x
            self.cnt[x]+=self.cnt[y]
            if self.depth[x]==self.depth[y]:
                self.depth[x]+=1
    def same(self, x, y):
        return self.find(x)==self.find(y)
    def size(self,x):
        return self.cnt[self.find(x)]

n,m = map(int,input().split())
utree = UnionFind(n+10)
for _ in range(m):
    x,y,z = map(int,input().split())
    utree.unite(x,y)
s = {utree.find(i) for i in range(1,n+1)}
print(len(s))

Submission status: Accepted

Solution code:
class UnionFind:
    def __init__(self, max_size):
        self.parent = [i for i in range(max_size+1)]
        self.depth = [0 for _ in range(max_size+1)]
        self.cnt = [1 for i in range(max_size+1)]
    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
        elif self.depth[x]<self.depth[y]:
            self.parent[x] = y
            self.cnt[y] += self.cnt[x]
        else:
            self.parent[y] = x
            self.cnt[x]+=self.cnt[y]
            if self.depth[x]==self.depth[y]:
                self.depth[x]+=1
    def same(self, x, y):
        return self.find(x)==self.find(y)
    def size(self,x):
        return self.cnt[self.find(x)]

n,m = map(int,input().split())
utree = UnionFind(n+10)
for _ in range(m):
    x,y,z = map(int,input().split())
    utree.unite(x,y)
l = [utree.find(i) for i in range(1,n+1)]
print(len(set(l)))

Submission status: Accepted

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(10**9)
input = sys.stdin.readline
n, m = map(int, input().split())
memo = [1 for _ in range(n)]
E = [[] for _ in range(n)]
for i in range(m):
    x, y, z = map(int, input().split())
    E[x-1].append(y-1)
    E[y-1].append(x-1)
def dfs(cur, pre):
    stack = deque([[cur, pre]])
    while stack:
        cur, pre = stack.pop()
        memo[cur] = 0
        for e in E[cur]:
            if e != pre and memo[e]:
                stack.append([e, cur])
ans = 0
for i in range(n):
    if memo[i]:
        dfs(i, -1)
        ans += 1
print(ans)

Submission status: Accepted

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(10**9)
input = sys.stdin.readline
n, m = map(int, input().split())
memo = set(list(range(n)))
E = [[] for i in range(n)]
for i in range(m):
    x, y, z = map(int, input().split())
    E[x-1].append(y-1)
    E[y-1].append(x-1)
def dfs(cur, pre):
    stack = deque([[cur, pre]])
    while stack:
        cur, pre = stack.pop()
        memo.discard(cur)
        for e in E[cur]:
            if e != pre and e in memo:
                stack.append([e, cur])
ans = 0
for i in range(n):
    if i in memo:
        dfs(i, -1)
        ans += 1
print(ans)

Submission status: Accepted

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(10**9)
input = sys.stdin.readline
n, m = map(int, input().split())
memo = set(list(range(n)))
E = [[] for i in range(n)]
for i in range(m):
    x, y, z = map(int, input().split())
    E[x-1].append(y-1)
    E[y-1].append(x-1)
def dfs(cur, pre):
    stack = deque([[cur, pre]])
    while stack:
        cur, pre = stack.pop()
        if pre != -1:
            memo.discard(cur)
        for e in E[cur]:
            if e != pre and e in memo:
                stack.append([e, cur])
ans = 0
while len(memo):
    cur = memo.pop()
    dfs(cur, -1)
    ans += 1
print(ans)

Submission status: Accepted

Solution code:
class UnionFind:
  
  def __init__(self, n):
    self.par = [i for i in range(n)]
    self.rank = [0]*n
    self.num = n
  def find(self, x):
    if self.par[x]==x:
      return x
    else:
      self.par[x] = self.find(self.par[x])
      return self.par[x]
  
  def unite(self, x, y):
    x = self.find(x)
    y = self.find(y)
    if x==y:
      return
    self.num -= 1
    if self.rank[x]<self.rank[y]:
      self.par[x] = y
    else:
      self.par[y] = x
      if self.rank[x]==self.rank[y]:
        self.rank[x] += 1
  
  def same(self, x, y):
    return self.find(x)==self.find(y)
  
  def psize(self):
    return self.num

N, M = map(int, input().split())
union = UnionFind(N)
for i in range(M):
  x, y, z = map(int, input().split())
  union.unite(x-1, y-1)
for i in range(N):
  m = union.find(i)
ans = set(union.par)
print(len(ans))

Submission status: Accepted

Solution code:
class UnionFind:
  
  def __init__(self, n):
    self.par = [i for i in range(n)]
    self.rank = [0]*n
    self.size = n
  def find(self, x):
    if self.par[x]==x:
      return x
    else:
      self.par[x] = self.find(self.par[x])
      return self.par[x]
  
  def unite(self, x, y):
    x = self.find(x)
    y = self.find(y)
    if x==y:
      return
    self.size -= 1
    if self.rank[x]<self.rank[y]:
      self.par[x] = y
    else:
      self.par[y] = x
      if self.rank[x]==self.rank[y]:
        self.rank[x] += 1
  
  def same(self, x, y):
    return self.find(x)==self.find(y)
  
  def size(self):
    return len(set(self.par))

N, M = map(int, input().split())
union = UnionFind(N)
for i in range(M):
  x, y, z = map(int, input().split())
  union.unite(x-1, y-1)

print(union.size)

Submission status: Accepted

Solution code:
N, M = map(int, input().split())
XYZ = [list(map(int, input().split())) for _ in range(M)]

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())
                     
uf = UnionFind(N)
for xyz in XYZ:
  x, y, z = xyz                       
  uf.union(x - 1, y - 1)
print(uf.group_count())

Submission status: Accepted

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

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 roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

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

def main():
    N, M = map(int, input().split())
    uni = UnionFind(N)
    for _ in range(M):
        X, Y, Z = map(int, input().split())
        X -= 1
        Y -= 1
        uni.union(X,Y)

    print(uni.group_count())



if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
class UnionFind:
    def __init__(self, n):
        self.par = list(range(n))
        self.rank = [0] * n
        self.size = [1] * n

    def find(self, x):
        if self.par[x] == x:
            return x
        self.par[x] = self.find(self.par[x])
        return self.par[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.par[x] = y
            x, y = y, x
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
        self.size[x] += self.size[y]

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

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


def p_e():
    n, m = map(int, input().split())
    uf = UnionFind(n)
    for _ in range(m):
        x, y, z = map(int, input().split())
        uf.unite(x - 1, y - 1)
    ans = set()
    for i in range(n):
        ans.add(uf.find(i))
    print(len(ans))
    

if __name__ == '__main__':
    p_e()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**6)
n, m = map(int, input().split())
adjacent_list = [[] for i in range(n + 1)]
for i in range(m):
    x, y, z = map(int,input().split())
    adjacent_list[x].append(y)
    adjacent_list[y].append(x)
##結局、グラフが何個あるか数える
finished = set()
ans = 0
def dfs(node):
    global finished
    finished.add(node)
    for i in adjacent_list[node]:
        if i not in finished:
            dfs(i)

while len(finished) != n:
    for i in range(1,n+1):
        if i not in finished:
            dfs(i)
            ans += 1
print(ans)

Submission status: Accepted

Solution code:
#17:11
n,m = map(int,input().split())
pre = [i for i in range(n)]
ans = n
for _ in range(m):
  x,y,z = map(int,input().split())
  x -= 1
  y -= 1
  X = [x]
  Y = [y]
  while pre[x] != x:
    X.append(x)
    x = pre[x]
  while pre[y] != y:
    Y.append(y)
    y = pre[y]
  if x != y:
    ans -= 1
    for xx in X:
      pre[xx] = y
    for yy in Y:
      pre[yy] = y
    pre[x] = y
#print(pre)
print(ans)

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
    
    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 root_len(self):
    count = 0
    for i in self.parents:
      if i < 0:
        count += 1
    
    return count
    
n,m = map(int,input().split())

uf = UnionFind(n)

for i in range(m):
  x,y,z = map(int,input().split())
  
  uf.union(x-1,y-1)
  
print(uf.root_len())

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
    
    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 
    
    self.parents[y] = x
    
  def root_len(self):
    count = 0
    for i in self.parents:
      if i < 0:
        count += 1
    
    return count
    
n,m = map(int,input().split())

uf = UnionFind(n)

for i in range(m):
  x,y,z = map(int,input().split())
  
  uf.union(x-1,y-1)
  
print(uf.root_len())

Submission status: Accepted

Solution code:
import sys

input = sys.stdin.readline

ri = lambda: int(input())
rs = lambda: input().rstrip()
ril = lambda: list(map(int, input().split()))
rsl = lambda: input().rstrip().split()
ris = lambda n: [ri() for _ in range(n)]
rss = lambda n: [rs() for _ in range(n)]
rils = lambda n: [ril() for _ in range(n)]
rsls = lambda n: [rsl() for _ in range(n)]


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = list(range(n))
        self.ranks = [0 for _ in range(n)]

    def get_root(self, x):
        if self.parents[x] == x:
            return x
        self.parents[x] = self.get_root(self.parents[x])
        return self.parents[x]

    def merge(self, x, y):
        x = self.get_root(x)
        y = self.get_root(y)
        if x != y:
            if self.ranks[x] < self.ranks[y]:
                self.parents[x] = y
            else:
                self.parents[y] = x
                if self.ranks[x] == self.ranks[y]:
                    self.ranks[x] += 1


n, m = ril()
uf = UnionFind(n)
for _ in range(m):
    x, y, z = ril()
    uf.merge(x - 1, y - 1)
for i in range(n):
    uf.get_root(i)
print(len(set(uf.parents)))

Submission status: Accepted

Solution code:
import sys

input = sys.stdin.readline

ri = lambda: int(input())
rs = lambda: input().rstrip()
ril = lambda: list(map(int, input().split()))
rsl = lambda: input().rstrip().split()
ris = lambda n: [ri() for _ in range(n)]
rss = lambda n: [rs() for _ in range(n)]
rils = lambda n: [ril() for _ in range(n)]
rsls = lambda n: [rsl() for _ in range(n)]


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = list(range(n))
        self.ranks = [0 for _ in range(n)]

    def get_root(self, x):
        if self.parents[x] == x:
            return x
        self.parents[x] = self.get_root(self.parents[x])
        return self.parents[x]

    def merge(self, x, y):
        x = self.get_root(x)
        y = self.get_root(y)
        if x != y:
            if self.ranks[x] < self.ranks[y]:
                self.parents[x] = y
            else:
                self.parents[y] = x
                if self.ranks[x] == self.ranks[y]:
                    self.ranks[x] += 1


n, m = ril()
uf = UnionFind(n)
for _ in range(m):
    x, y, z = ril()
    uf.merge(x - 1, y - 1)
res = set()
for i in range(n):
    res.add(uf.get_root(i))
print(len(res))

Submission status: Accepted

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

class CountTree():
  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 roots(self):
    return [i for i,x in enumerate(self.parents) if x<0]
  def group_count(self):
    return len(self.roots())
  
def solve():
  n,m=(int(i) for i in input().split())
  ct=CountTree(n)
  for i in range(m):
    x,y,z=[int(i) for i in input().split()]
    ct.union(x-1,y-1)
  print(ct.group_count())
solve()

Submission status: Accepted

Solution code:
class union_find():
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [1 for i in range(n + 1)]

    def find(self, c):
        if self.par[c] == c:
            return c

        ret = self.find(self.par[c])
        self.par[c] = ret
        return ret

    def union(self, x, y):
        xr = self.find(x)
        yr = self.find(y)
        if xr == yr:
            return

        if self.rank[yr] > self.rank[xr]:
            self.par[xr] = yr
        else:
            self.par[yr] = xr
            if self.rank[xr] == self.rank[yr]:
                self.rank[xr] += 1

    def show(self):
        print('parent', self.par[1:])
        print('rank', self.rank[1:])

N, M = map(int, input().split())
uf = union_find(N)

for i in range(M):
    x, y, z = map(int, input().split())
    uf.union(x, y)


print([i == v for i, v in enumerate(uf.par)].count(True) - 1)

Submission status: Accepted

Solution code:
import sys


input = sys.stdin.readline


def main():
    N, M = map(int, input().split())
    alist = [set([]) for _ in range(N+1)]
    for _ in range(M):
        X, Y, _ = map(int, input().split())
        alist[X].add(Y)
        alist[Y].add(X)

    f = [0]*(N+1)
    f[0] = 1
    stack = []
    ans = 0
    for i in range(1, N+1):
        if len(alist[i]) and not f[i]:
            stack.append(i)
            ans += 1
        elif not len(alist[i]):
            ans += 1
        while len(stack):
            n = stack.pop()
            f[n] = 1
            for m in alist[n]:
                if not f[m]:
                    stack.append(m)

    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
    n, m = map(int, input().split())
    xyz = [list(map(int, input().split())) for _ in [0] * m]
    g = [[] for _ in [0] * n]
    for x,y,z in xyz:
        g[x - 1].append(y - 1)
        g[y - 1].append(x - 1)
    v = [False] * n
    cnt=0
    for i in range(n):
        if v[i]:
            continue
        cnt+=1
        q = [i]
        v[i]=True
        while q:
            j = q.pop()
            for k in g[j]:
                if v[k] == False:
                    q.append(k)
                    v[k]=True                
    print(cnt)
main()

Submission status: Accepted

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

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())
        
        
n,m = map(int,input().split())

uf = UnionFind(n)
for _ in range(m):
    x,y,z = map(int,input().split())
    uf.union(x-1, y-1)
    
print(uf.group_count())

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(1000000)
n,m=map(int,input().split())
lb=[0 for i in range(n)]
l=[[] for i in range(n+1)]
for i in range(m):
  x,y,z=map(int,input().split())
  l[x].append(y)
  l[y].append(x)
def dfs(a,num):
  if lb[a-1]!=0:
    pass
  else:
    lb[a-1]=num
    for i in l[a]:
      dfs(i,num)
  return None
for i in range(n):
  dfs(i+1,i+1)
count=0
laa=[0 for i in range(n+1)]
for i in range(n):
  if lb[i]==0:
    count+=1
  elif laa[lb[i]]==0:
    count+=1
    laa[lb[i]]=1
  else:
    pass
print(count)

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
a = [i for i in range(n + 1)]
def find(a, x):
    if a[x] != x:
        a[x] = find(a, a[x])
    return a[x]
 
 
def unite(a, x, y):
    x = find(a, x)
    y = find(a, y)
    if x != y:
        a[x] = min(x, y)
        a[y] = a[x]
for i in range(m):
  x,y,z=map(int,input().split())
  unite(a,x,y)
ans = -1
for i, v in enumerate(a):
    if i == v:
        ans += 1

print(ans)

Submission status: Accepted

Solution code:
n,m=map(int,input().split())
class UnionFind:
    def __init__(self, n):
        self.par =[i for i in range(n+1)]
        self.rank = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            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 self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)
A=UnionFind(n)
for i in range(m):
    a,b,c=map(int,input().split())
    A.union(a,b)
List=A.par
counter=0
for j in range(n+1):
    if List[j]==j:
        counter+=1
print(counter-1)

Submission status: Accepted

Solution code:
n,m=map(int,input().split())
xy=[]
data=[[] for i in range(n+1)]
for _ in range(m):
    x,y,z=map(int,input().split())
    xy.append([x,y])
    data[x].append(y)
    data[y].append(x)
flag=[0]*(n+1)
count=0
for i in range(1,n+1):
    if flag[i]==0:
        count+=1
        flag[i]=1
        que=[i]
        while que:
            h=que.pop()
            for u in data[h]:
                if flag[u]==0:
                    flag[u]=1
                    que.append(u)
print(count)

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()
class UnionFind(object):
    def __init__(self,n):
        self.__par=list(range(n))
        self.__rank=[0]*n
        self.__size=[1]*n
        self.__connected=n

    def root(self,k):
        if(self.__par[k]==k): return k
        self.__par[k]=self.root(self.__par[k])
        return self.__par[k]

    def unite(self,i,j):
        i=self.root(i); j=self.root(j)
        par=self.__par; rank=self.__rank; size=self.__size
        if(i==j): return False
        if(rank[i]>rank[j]):
            par[j]=i
            size[i]+=size[j]
        else:
            par[i]=j
            size[j]+=size[i]
            if(rank[i]==rank[j]): rank[j]+=1
        self.__connected-=1
        return True

    def size(self,k):
        return self.__size[self.root(k)]

    def connected(self):
        return self.__connected

def resolve():
    n,m=map(int,input().split())
    uf=UnionFind(n)
    for _ in range(m):
        x,y,z=map(int,input().split())
        x-=1; y-=1
        uf.unite(x,y)
    print(uf.connected())
resolve()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()
def resolve():
    n,m=map(int,input().split())
    E=[[] for _ in range(n)]
    for _ in range(m):
        x,y,z=map(int,input().split())
        x-=1; y-=1
        E[x].append(y)
        E[y].append(x)

    visited=[0]*n
    def dfs(v)->bool:
        if(visited[v]):
            return False
        visited[v]=1
        for nv in E[v]:
            dfs(nv)
        return True

    ans=0
    for v in range(n):
        ans+=dfs(v)
    print(ans)
resolve()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()
class UnionFind(object):
    def __init__(self,n):
        self.__par=list(range(n))
        self.__rank=[0]*n
        self.__size=[1]*n

    def root(self,k):
        if(self.__par[k]==k): return k
        self.__par[k]=self.root(self.__par[k])
        return self.__par[k]

    def unite(self,i,j):
        i=self.root(i); j=self.root(j)
        par=self.__par; rank=self.__rank; size=self.__size
        if(i==j): return False
        if(rank[i]>rank[j]):
            par[j]=i
            size[i]+=size[j]
        else:
            par[i]=j
            size[j]+=size[i]
            if(rank[i]==rank[j]): rank[j]+=1
        return True

    def size(self,k):
        return self.__size[self.root(k)]

def resolve():
    n,m=map(int,input().split())
    uf=UnionFind(n)
    for _ in range(m):
        x,y,z=map(int,input().split())
        x-=1; y-=1
        uf.unite(x,y)
    print(len({uf.root(i) for i in range(n)}))
resolve()

Submission status: Accepted

Solution code:
class UnionFind(object):
    def __init__(self, N):
        self.parent = [-1] * N #parent[i] は(i+1)番目の要素が含まれる要素数の(-1)倍
    #要素が負-->その数を親とするグループに属する要素の数×(-1)
    #要素が正-->親のindex

    #Aがどのグループに属しているかを調べる
    def root(self, A):
        if self.parent[A-1] < 0: #負の数-->その数は親
            return A
        self.parent[A-1] = self.root(self.parent[A-1]) #負では無い時、親の場所が入っているから、親が属しているグループを、自分自身に入れる(一度確認したところは直接親を見れるようにする)
        return self.parent[A-1] #親の位置を返す

    #Aが含まれているグループに属している数を返す
    def size(self, A):
        return -1 * self.parent[self.root(A)-1]

    #AとBをくっ付ける
    def connect(self, A, B):
        A = self.root(A) #Aを含むグループの親を返す
        B = self.root(B) #Bを含むグループの親を返す
        if A == B: #親が同じならなにもしない
            return False
        
        #大きい方(A)に小さい方(B)をつなぎたい
        if self.size(A) < self.size(B): #大小関係が逆の時は入れ替える
            A, B = B, A
        
        self.parent[A-1] += self.parent[B-1] #大きい方に小さい方を加える　（負の数＋負の数 = 新しいグループに含まれる数×(-1)）
        self.parent[B-1] = A #加えられた親の値を、加えた先の親の位置に書き変える
        return True
    
    def same(self, A, B):
        if self.root(A) == self.root(B):
            return True
        else:
            return False
            
# N, Q = map(int, input().split())
# uni = UnionFind(N)
# for _ in range(Q):
#     P, A, B = map(int, input().split())
#     if P == 1:
#         if uni.root(A) == uni.root(B): #親が同じかどうか
#             print ('Yes')
#         else:
#             print ('No')
#     else:
#         uni.connect(A, B)

N, M = map(int, input().split())
uni = UnionFind(N)
ans = N
for _ in range(M):
    x, y, z = map(int, input().split())
    x -= 1
    y -= 1
    if uni.root(x) == uni.root(y): #親が同じ時
        pass
    else:
        ans -= 1
        uni.connect(x, y)

print (ans)

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**5+10)
input = sys.stdin.readline
def dfs(v,G,visit):
    visit[v-1]=1    
    for next in G[v-1]:        
        if visit[next-1]:
            continue
        _ = dfs(next,G,visit) 
 
N, M =map(int, input().split())
G  = [[] for _ in range(N)]
for i in range(M):
    a,b ,_= map(int, input().split())
    G[a-1].append(b)
    G[b-1].append(a)
    
count = 0

visit = [0]*N
for i in range(1,N+1):
  if visit[i-1]:
    continue
  if G[i-1]:  
    _ = dfs(i,G,visit)
  else:
    visit[i-1] = 1
  count += 1

print(count)

Submission status: Accepted

Solution code:
import numpy as np
import sys
sys.setrecursionlimit(10**5+1)
input = sys.stdin.readline

def dfs(v,G,visit):
    visit[v-1]=1    
    for next in G[v-1]:        
        if visit[next-1]:
            continue
        _ = dfs(next,G,visit) 
 
N, M =map(int, input().split())
G  = [[] for _ in range(N)]
for i in range(M):
    a,b ,_= map(int, input().split())
    G[a-1].append(b)
    G[b-1].append(a)
 
count = 0

visit = np.array([0]*N)
for i in range(1,N+1):
  if visit[i-1]:
    continue
  if G[i-1]:  
    _ = dfs(i,G,visit)
  else:
    visit[i-1] = 1
  count += 1

print(count)

Submission status: Accepted

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

parent=[i for i in range(n)]
rank=[0 for i in range(n)]

def find(a):
  if parent[a]==a:
    return a
  else:
    return find(parent[a])

def union(a,b):
  ar=find(a)
  br=find(b)
  if ar==br:
    return
  if rank[a]>rank[b]:
    parent[br]=ar
  else:
    parent[ar]=br
    if rank[a]==rank[b]:
      rank[a]+=1
      
def same(a,b):
  ar=find(a)
  br=find(b)
  return ar==br

q=[None]*m

for i in range(m):
  x,y,z=map(int,input().split())
  q[i]=[x-1,y-1]

for i in range(len(q)):
  union(q[i][0],q[i][1])
  
roots=[0]*len(parent)
for i in range(len(parent)):
  roots[i]=find(i)

print(len(set(roots)))

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(1000000)
from collections import deque
def getN():
    return int(input())
def getList():
    return list(map(int, input().split()))
import math
from collections import deque

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)


    def find(self, x):
        if self.par[x] == x:
            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 self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1


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

    def update_all(self):
        for i in range(n+1):
            self.par[i] = self.find(i)


n, m = getList()

UF = UnionFind(n)
for i in range(m):
    a, b, c = getList()
    if not UF.same_check(a, b):
        UF.union(a, b)

UF.update_all()

print(len(list(set(UF.par))) - 1)