Solution to a problem P5089 [[eJOI2018] Periodic Table]

Topic Link

Solution [eJOI2018] Periodic Table of Elements

Subject to the effect: If there are three corners of a rectangle is marked, and the other corner will be marked manually find the minimum number of points to be marked so that there are already some marks are labeled whole matrix

Analysis: This question really immortal ideas

May be a conventional routine, the entire \ (n-\) OK \ (m \) columns of the matrix considered as a bipartite graph, our goal is clearly in FIG complete bipartite graph is a

Let's look at nuclear fusion equation, we find the edge of any course newly added after fusion in which the original components Unicom, China Unicom is to say it does not change the number of components

The question is: have some side of a bipartite graph, and asked how many sides can at least add it to become complete bipartite graph

Obviously the answer is equal to the number of communication components \ (- 1 \) , may be disjoint-set maintenance

#include <cstdio>
#include <cctype>
using namespace std;
const int maxn = 5e5 + 100;
inline int read(){
    int x = 0;char c = getchar();
    while(!isdigit(c))c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x;
}
struct union_set{
    int f[maxn],siz;
    inline void init(int n){
        siz = n;
        for(int i = 1;i <= n;i++)f[i] = i;
    }
    inline int find(int x){
        return (x == f[x]) ? x : (f[x] = find(f[x]));
    }
    inline void merge(int a,int b){
        int x = find(a),y = find(b);
        if(x != y){
            siz--;
            f[x] = y;
        }
    }
}s;
int n,m,q;
int main(){
    n = read(),m = read(),q = read();
    s.init(n + m);
    for(int x,y,i = 1;i <= q;i++)
        x = read(),y = read() + n,s.merge(x,y);
    printf("%d\n",s.siz - 1);
    return 0;
}

Guess you like

Origin www.cnblogs.com/colazcy/p/11562828.html