• Codeforces 1012B Chemical table (思维+二分图)


    <题目链接>

    题目大意:
    给定一个n*m的矩阵网格,向其中加点,对于一个组成矩形的四个点中如果有三个点中有元素,那么第四个点中会自动产生新的元素。问你最少再加多少个点能够填满这个网格。
    解题分析:
    不是很好想,先将行列看成两个集合,每次加点操作,就相当于x集合向y集合连了一条边。
    本题可以巧妙的转化为,要使x和y集合所有的点都连通最少需要添加几条边。初始情况需要n+m-1条边(因为两个集合有n+m个点,且相同集合不能连边)。
    然后根据题目已经给出的边判断最终的连通块个数,用并查集来判连通。主要是这个转化的思想不好想。

    #include <bits/stdc++.h>
    using namespace std;
    
    template<typename T>
    inline void read(T&x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){ if(c=='-')f=-1;c=getchar(); }
        while(c>='0'&&c<='9'){ x=x*10+c-'0';c=getchar(); }
        x*=f;
    }
    #define REP(i,s,t) for(int i=s;i<=t;i++)
    const int N = 2e5+5;
    int fa[N<<1];
    
    int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); }
    
    inline bool merge(int x,int y){
        int f1=find(x),f2=find(y);
        if(f1!=f2){ fa[f1]=f2;return true;}
        return false;
    }
    
    int main(){
        int n,m,q;
        read(n);read(m);read(q);
        REP(i,0,n+m)fa[i]=i;
        int ans=n+m-1;       //其实就是最少用多少条边,使得这n+m个点连通,最多只需要用n+m-1条
        REP(i,1,q){
            int a,b;read(a);read(b);
            b+=n;
            if(merge(a,b))ans--;      //如果这条边有效,则需要的边数--
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    oracle ORA01001,请求资源正忙或无效
    Flex[Embed(source='assets/error.png')]无法解析用于转换的代码错误
    正在覆盖未标记为 override 的函数
    LINUX umask详解
    C++服务器学习路线
    计算kappa系数
    umask的含义及设置
    Seurat的各种数据成员访问
    GAN训练判别器和生成器时的顺序与detach
    autograd.grad 学习
  • 原文地址:https://www.cnblogs.com/00isok/p/10990806.html
Copyright © 2020-2023  润新知