CF1012B Chemical table 构造_思维_并查集

我们可以将横坐标和纵坐标看成是点。发现这些点之间是有传递性的。
题中说明,如果有矩阵中三个顶点被选,则底角的点也会被覆盖,发现这些点之间是有传递性的。那么我们最终达到的目的就是使整个图中只有 11 个集合。而将两个集合合并的代价是新覆盖一个点。于是我们只需统计初始局面中图中有多少个集合,并输出集合数量 - 1 即可。
Code:

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 2000000 + 3;
int p[maxn];
bool vis[maxn];
inline int find(int x){ return p[x] == x ? x : p[x] = find(p[x]); }
inline void init(){ for(int i = 1;i < maxn - 2; ++i) p[i] = i;}
inline void merge(int a,int b){
    int x = find(a), y = find(b);
    if(x == y) return ;
    p[x] = y;
}
int main()
{
    init();
    int n,m,q;
    cin >> n >> m >> q;
    for(int i = 1;i <= q; ++i)
    {
        int a,b;
        cin >> a >> b;
        merge(a,n + b);
    }
    int ans = 0;
    for(int i = 1;i <= n + m; ++i)
    {
        int root = find(i);
        if(!vis[root]){
            vis[root] = true;
            ++ans;
        }
    }
    cout << ans - 1;
    return 0;
}
posted @ 2018-10-14 10:27  EM-LGH  阅读(152)  评论(0编辑  收藏  举报