zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    java里面嵌套执行python脚本
    session的token令牌机制防止表单重复提交
    springIOC实现原理模拟(springIOC底层使用xml解析+反射实现)
    service层使用接口的好处
    javap -verbose输出结果详解
    skiplist
    Jmeter内存溢出解决方法
    Jmeter参数化设置的5种方法
    方法入参获取泛型类型
    并发编程笔记
  • 原文地址:https://www.cnblogs.com/00isok/p/10990806.html
Copyright © 2011-2022 走看看