Peaceful Rooks (Codeforces 1411C)
Tags: Others, dsu

You are given a $$$n \times n$$$ chessboard. Rows and columns of the board are numbered from $$$1$$$ to $$$n$$$. Cell $$$(x, y)$$$ lies on the intersection of column number $$$x$$$ and row number $$$y$$$.Rook is a chess piece, that can in one turn move any number of cells vertically or horizontally. There are $$$m$$$ rooks ($$$m < n$$$) placed on the chessboard in such a way that no pair of rooks attack each other. I.e. there are no pair of rooks that share a row or a column.In one turn you can move one of the rooks any number of cells vertically or horizontally. Additionally, it shouldn't be attacked by any other rook after movement. What is the minimum number of moves required to place all the rooks on the main diagonal?The main diagonal of the chessboard is all the cells $$$(i, i)$$$, where $$$1 \le i \le n$$$.

Input: The first line contains the number of test cases $$$t$$$ ($$$1 \leq t \leq 10^3$$$). Description of the $$$t$$$ test cases follows.The first line of each test case contains two integers $$$n$$$ and $$$m$$$ — size of the chessboard and the number of rooks ($$$2 \leq n \leq 10^5$$$, $$$1 \leq m < n$$$). Each of the next $$$m$$$ lines contains two integers $$$x_i$$$ and $$$y_i$$$ — positions of rooks, $$$i$$$-th rook is placed in the cell $$$(x_i, y_i)$$$ ($$$1 \leq x_i, y_i \leq n$$$). It's guaranteed that no two rooks attack each other in the initial placement.The sum of $$$n$$$ over all test cases does not exceed $$$10^5$$$.

Output: For each of $$$t$$$ test cases print a single integer — the minimum number of moves required to place all the rooks on the main diagonal.It can be proved that this is always possible.

Note: Possible moves for the first three test cases:  $$$(2, 3) \to (2, 2)$$$  $$$(2, 1) \to (2, 3)$$$, $$$(1, 2) \to (1, 1)$$$, $$$(2, 3) \to (2, 2)$$$  $$$(2, 3) \to (2, 4)$$$, $$$(2, 4) \to (4, 4)$$$, $$$(3, 1) \to (3, 3)$$$, $$$(1, 2) \to (1, 1)$$$ 

Sample Inputs:
4
3 1
2 3
3 2
2 1
1 2
5 3
2 3
3 1
1 2
5 4
4 5
5 1
2 2
3 3

Sample Outputs:
1
3
4
2

Solution (Python):
def dsu(x):
    p = x
    while v[x] != x:
        x = v[x]
        v[p] = x
    return x
for _ in range(int(input())):
    (n, m) = map(int, input().split())
    ans = 0
    v = [i for i in range(n + 1)]
    ans = 0
    for _ in range(m):
        (a, b) = map(int, input().split())
        if a == b:
            continue
        ans += 1
        p = dsu(a)
        q = dsu(b)
        if p != q:
            v[p] = v[q]
        else:
            ans += 1
    print(ans)

Solution (Python):
def main():
    arr = [0] * 100001
    for _ in range(int(input())):
        (size, count) = map(int, input().split())
        for i in range(count):
            (x, y) = map(int, input().split())
            arr[x] = y
        cycles = 0
        petly = 0
        for i in range(1, size + 1):
            if arr[i] == i:
                petly += 1
                arr[i] = 0
            k = i
            while arr[k] != 0:
                temp = arr[k]
                arr[k] = 0
                k = temp
                if arr[k] == i:
                    cycles += 1
                    break
        print(count - petly + cycles)
main()

Solution (Python):
def main():
    out = ''
    arr = [0] * 100001
    for _ in range(int(input())):
        (size, count) = map(int, input().split())
        for i in range(count):
            (x, y) = map(int, input().split())
            arr[x] = y
        cycles = 0
        petly = 0
        for i in range(1, size + 1):
            if arr[i] == i:
                petly += 1
                arr[i] = 0
            k = i
            while arr[k] != 0:
                temp = arr[k]
                arr[k] = 0
                k = temp
                if arr[k] == i:
                    cycles += 1
                    break
        out += str(count - petly + cycles) + '\n'
    print(out)
main()