package main import . "fmt" import . "os" import bf "bufio" func main() { rd:=bf.NewReader(Stdin) var n,m int Fscan(rd,&n,&m) table := make([][]int, n+1) for i := 0; i < n; i++ { var b, c int Fscan(rd,&b,&c) table[c] = append(table[c], b) } ans := 0 for _, bs := range table { for i := 0; i < len(bs)-1; i++ { if bs[i] == bs[i+1] { continue } if isSame(bs[i],bs[i+1]) { continue } union(bs[i],bs[i+1]) ans++ } } Println(ans) } var group [2e5+10]int var place [2e5+10]int var groupId int = 0 func getGroup(a int) int { g := place[a] for g != group[g] { g = group[g] } place[a] = g return g } func isSame(a, b int) bool { ga := getGroup(a) gb := getGroup(b) return ga != 0 && ga == gb } func union(a, b int) { ga := getGroup(a) gb := getGroup(b) switch { case ga == 0 && gb == 0: groupId++ place[a] = groupId place[b] = groupId group[groupId] = groupId case ga == 0: place[a] = gb case gb == 0: place[b] = ga default: ga,gb = min(ga,gb),max(ga,gb) group[gb] = ga } } /* 考察 UnionFind使う問題ぽく感じる 実装うろ覚えなのでうまくいくか・・・? WAした理由が予想つかない 難問だ */