CF-1012B Chemical table (bipartite graph, disjoint-set)

Original title connection :

Question is intended : to a \ (N \ times M \) board for any one of a rectangular board is composed of any four points, wherein if the fourth corner pieces present a triangular automatically generates a board covered the entire piece we seek at least To how many pieces on the chessboard Riga

Idea : To be honest the beginning is not easy to think about how to solve. The presence of two points, that is, in the end pieces which can be given up to launch a new piece, and in the end how the pieces can make up at least make checkerboard finished up.

We can first analyze the relationship between the three pieces of four pieces form: Given a three-point \ ((x_1, Y_1) \) \ ((x_1, y_2) \) \ ((x_2, Y_1) \) can be introduced first three pieces \ ((x_2, Y_2) \) , we know that the two points is connected to one side of another side has a fixed rectangular \ (X \) or \ (Y \) coordinate

That selection will pass the ranks of the connection relationship. \ ((x_1, y_1) \ ) i.e. \ (x_1 \) connected \ (Y_1 \) , in the \ ((x_1, y_2) \ ) into it, ie \ (x_1 \) connected \ (Y_2 \) so \ ( x_1, y_1, y_2 \) three points was determined. So if done before the bipartite think this will be better connected relationship. We put this into two matrix converter of FIG each line is represented by a subscript, each column is represented by a subscript. All our points should have said that is complete bipartite graph node you want to connect all ranks represented. Here we can use the disjoint-set to merge sets, relations between the ranks of the connection.

code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
int pre[maxn<<1];
int n,m,q;
int find(int x){
    return x==pre[x]?x:pre[x]=find(pre[x]);
}
bool unite(int x,int y){
    int fx,fy;
    fx = find(x),fy = find(y);
    if(fx!=fy){ pre[fx]=fy;return true;}
    return false;
}
int main(){

    while(cin>>n>>m>>q){
        for(int i=0;i<=n+m;i++){
            pre[i] = i;
        }    
        int ans = n+m-1;
        for(int i=0;i<q;i++){
            int x,y;
            cin>>x>>y;
            if(unite(x,y+n)) ans--;
        }
        printf("%d\n",ans);
    }
}

Guess you like

Origin www.cnblogs.com/Tianwell/p/11403850.html