AtCoder problem 012

C++ solution:


Python solution: # でつoO(YOU PLAY WITH THE CARDS YOU'RE DEALT..)
from typing import Iterable, List
import sys
def main():
    input = sys.stdin.readline
    H, W = map(int, input().split())
    Q = int(input())
    M = [[0] * W for _ in range(H)]
    uf = UnionFindTree(H * W)
    for _ in range(Q):
        t, *p = map(int, input().split())
        if t == 1:
            x, y = p
            x, y = x - 1, y - 1
            M[x][y] = 1
            for i, j in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)):
                if i < 0 or i >= H or j < 0 or j >= W: continue
                if M[i][j]:
                    uf.union(x * W + y, i * W + j)
        else:
            xa, ya, xb, yb = map(lambda x: x - 1, p)
            print('Yes' if M[xa][ya] and uf.same(xa * W + ya, xb * W + yb) else 'No')

class UnionFindTree:
    __slots__ = ('parent')

    def __init__(self, n: int) -> None:
        self.parent = [-1] * n

    def find(self, x: int) -> int:
        p = self.parent
        par, seq = p[x], []
        while par >= 0:
            seq.append(x)
            x, par = par, p[par]
        for c in seq: p[c] = x
        return x

    def union(self, x: int, y: int) -> bool:
        x, y, p = self.find(x), self.find(y), self.parent
        if x == y: return False
        if p[x] > p[y]: x, y = y, x
        p[x], p[y] = p[x] + p[y], x
        return True

    def same(self, x: int, y: int) -> bool:
        return self.find(x) == self.find(y)

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

    def same_all(self, indices: Iterable[int]) -> bool:
        f, v = self.find, self.find(indices[0])
        return all(f(i) == v for i in indices)

    def groups(self) -> List[int]:
        return [i for i, p in enumerate(self.parent) if p < 0]

if __name__ == '__main__':
    main()




Kuin solution: func main()
	var h: int :: cui@inputInt()
	var w: int :: cui@inputInt()
	var m: [][]bool :: #[h, w]bool
	var uni: UnionFind :: (#UnionFind).init(h * w)
	
	var q: int :: cui@inputInt()
	for(1, q)
		var t: int :: cui@inputInt()
		if(t = 1)
			var r: int :: cui@inputInt() - 1
			var c: int :: cui@inputInt() - 1
			do m[r][c] :: true
			var u: int :: r * w + c
			var dx: []int :: [1, 0, -1, 0]
			var dy: []int :: [0, 1, 0, -1]
			for i(0, 3)
				var c2: int :: c + dx[i]
				var r2: int :: r + dy[i]
				if(c2 < 0 | w <= c2)
					skip i
				end if
				if(r2 < 0 | h <= r2)
					skip i
				end if
				if(!m[r2][c2])
					skip i
				end if
				var v: int :: r2 * w + c2
				do uni.unite(u, v)
			end for
		else
			var ra: int :: cui@inputInt() - 1
			var ca: int :: cui@inputInt() - 1
			var rb: int :: cui@inputInt() - 1
			var cb: int :: cui@inputInt() - 1
			var ans: bool :: false
			if(m[ra][ca] & m[rb][cb])
				do ans :: uni.same(ra * w + ca, rb * w + cb)
			end if
			do cui@print(ans ?("Yes\n", "No\n"))
		end if
	end for
	
	class UnionFind()
		var parents: []int
		+func init(n: int): UnionFind
			do me.parents :: [-1].repeat(n)
			ret me
		end func
		+func size(x: int): int
			ret - me.parents[me.root(x)]
		end func
		+func same(x: int, y: int): bool
			ret me.root(x) = me.root(y)
		end func
		+func unite(x: int, y: int): bool
			do x :: me.root(x)
			do y :: me.root(y)
			if(x = y)
				ret false
			end if
			if(me.size(x) < me.size(y))
				do me.parents[y] :+ me.parents[x]
				do me.parents[x] :: y
			else
				do me.parents[x] :+ me.parents[y]
				do me.parents[y] :: x
			end if
			ret true
		end func
		
		func root(x: int): int
			if(me.parents[x] < 0)
				ret x
			else
				do me.parents[x] :: me.root(me.parents[x])
				ret me.parents[x]
			end if
		end func
	end class
end func