You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 1000 * 1000 + 10 ;
const int M = 2 * N ;
int n , m ;
// 二维转一维的办法,坐标从(1,1)开始
inline int get ( int x , int y ) {
// m为列宽
return ( x - 1 ) * m + y ;
}
struct Edge {
int a , b , w ;
const bool operator < ( const Edge & t ) const {
return w < t . w ;
}
} e [ M ] ;
int el ;
// 并查集
int p [ N ] ;
int find ( int x ) {
if ( p [ x ] ! = x ) p [ x ] = find ( p [ x ] ) ;
return p [ x ] ;
}
// 先连1的边, 再连2的边
void create_edges ( ) {
for ( int i = 1 ; i < = ( n - 1 ) * m ; i + + )
e [ el + + ] = { i , i + m , 1 } ; // i~i+m是一条纵向边
for ( int i = 1 ; i < = n * m ; i + + ) {
if ( i % m = = 0 ) continue ; // 最后一列放过
e [ el + + ] = { i , i + 1 , 2 } ;
}
// 因为加进去就是按边权由小到大录入的,所以不用再排序了
}
int main ( ) {
cin > > n > > m ;
// 建边
create_edges ( ) ;
// 并查集初始化
for ( int i = 1 ; i < = n * m ; i + + ) p [ i ] = i ;
int x1 , y1 , x2 , y2 ;
// 利用二维转一维办法,将(x,y)映射成节点编号
// 某些点之间已经有连线了=> 标识这些点已在并查集中
while ( cin > > x1 > > y1 > > x2 > > y2 ) {
int a = get ( x1 , y1 ) , b = get ( x2 , y2 ) ;
p [ find ( a ) ] = find ( b ) ;
}
int res = 0 ; // 用Kruskal算法即可
for ( int i = 0 ; i < el ; i + + ) {
int a = find ( e [ i ] . a ) , b = find ( e [ i ] . b ) , w = e [ i ] . w ;
if ( a ! = b ) p [ a ] = b , res + = w ;
}
printf ( " %d \n " , res ) ;
return 0 ;
}