zoukankan      html  css  js  c++  java
  • CF-1012B Chemical table(二分图,并查集)

    原题连接:

    题意:给一个 (N imes M) 棋盘 对于任何一个棋盘中的由任意四点构成的矩形,如果 其中三角存在棋子 则第四个角会自动生成一个棋子 求铺满整个棋盘 我们至少要向棋盘里加多少枚棋子

    思路:说实话一开始很不容易去想如何去解决。存在两点,即到底所给出的棋子能最多推出哪些新的棋子,以及到底怎样最少补棋子能够使得棋盘补完。

    我们可以先分析一下三个棋子形成四个棋子的关系: 已知三点 ((x_1,y_1)) ((x_1,y_2)) ((x_2,y_1)) 则可以推出第三个棋子 ((x_2,y_2)) ,我们知道两个点连接成的一条边已经固定了矩形另一条边的(x)或者(y)坐标

    即选择的行列会有传递连接关系。 ((x_1,y_1))(x_1) 连接 (y_1) ,在将((x_1,y_2)) 放进去即 (x_1) 连接 (y_2) 这样 (x_1,y_1,y_2)三个点就被确定了。所以如果做过以前的二分图就会更好想这个连接关系。我们把这个矩阵转换成两个图 把每行用一个下标表示,每列用一个下标表示。我们要把所有的点都表示完即是要将 行列所表示的二分图结点全部连接。我们这里可以使用并查集去合并集合,连接行列之间的关系。

    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
    ",ans);
        }
    }
    
  • 相关阅读:
    Unlicensed ARC session – terminating!
    ArcGIS读取dem格式数据
    OCIEnvCreate 失败,返回代码为 -1的解决方法
    PowerDesigner设计的数据库 ORA-0092
    Oracle空间查询 ORA-28595
    PowerDesigner添加表注释
    C# 动态解析表达式
    远程桌面不能交互复制粘贴
    ArcGIS10.4 Runtime Error R6034
    ArcGIS Add-in ValidateAddInXMLTask”任务意外失败
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11403850.html
Copyright © 2011-2022 走看看