• 2020牛客暑期多校第八场I-Interesting Computer Game(离散化+并查集)


    CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/107797019
    题目大意:给你T组数据,每组数据给你n对数,分别表示为(a_i,b_i(1leq a_i,b_ileq 10^9)),你每次都可以取其中的一个,但如果之前(a_i)已经被取过了,就不能再取了,(b_i)也是一样的。那么问你总共可以取多少种不同的数。((Tleq 10,nleq 1e5))

    输入
    2
    6
    1 2
    2 3
    3 4
    1 4
    1 3
    2 4
    5
    1 2
    1 2
    1 3
    2 3
    5 6

    输出
    Case #1: 4
    Case #2: 4

    emmm,开局就跑了波网络流。。。T了,后面nb队友过的。事实上我们可以将这些关系画出来,我们会发现,对于一个关系组,如果里面有环的话那么能够取得的数字就是整个图的大小,否则的话就只能取其大小-1个。至于判断有环无环,我们直接判断每次出现的两个数字是否有共同的祖先就可以了,然后我们可以传递这种关系。不过由于(a_i,b_i)比较大,所以我们要离散化一下,各位应该写得比较熟练了,先sort一下再unique一下,接着二分一下就完事了。不过注意的是father等并查集需要用到的数组也需要开到2倍空间大小。。。。我就因为这个卡了好久QAQ。。。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int mac=1e5+10;
    const int inf=1e9+10;
    
    int au[mac],av[mac];
    int num[mac<<1],father[mac<<1],bk[mac<<1];
    int sz[mac<<1],lu[mac],lv[mac];
    
    int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
    
    int main()
    {
        int t;
        scanf ("%d",&t);
        for (int cse=1; cse<=t; ++cse){
            int n,cnt=0;
            scanf ("%d",&n);
            for (int i=1; i<=n; i++){
                scanf ("%d%d",&au[i],&av[i]);
                num[++cnt]=au[i],num[++cnt]=av[i];
            }
            sort(num+1,num+1+cnt);
            int it=unique(num+1,num+1+cnt)-num;
            for (int i=1; i<=n; i++){
                lu[i]=lower_bound(num+1,num+it,au[i])-num;
                lv[i]=lower_bound(num+1,num+it,av[i])-num;
            }
            int ans=0;
            for (int i=1; i<it; i++) father[i]=i,bk[i]=0,sz[i]=1;
            for (int i=1; i<=n; i++){
            	int u=lu[i],v=lv[i];
            	int fu=find(u),fv=find(v);
            	if (fu!=fv){
            		father[fu]=fv;
            		sz[fv]+=sz[fu];
            		bk[fv]=max(bk[fv],bk[fu]);
            	}
            	else {
            		bk[fv]=1;
            	}
            }
            for (int i=1; i<it; i++){
            	if (father[i]!=i) continue;
            	ans+=sz[i]-1;
            	if (bk[i]) ans++;
            }
            printf ("Case #%d: %d
    ",cse,ans);
        }
        return 0;
    }
    
    路漫漫兮
  • 相关阅读:
    ssk文件 窗体皮肤
    子窗体加载时最大化出现异常不正常最大化显示
    android: ADB错误“more than one device and emulator”
    使用adb devices命令报:adb server version (39) doesn't match this client (41);killing
    测试需要关注的测试点以及测试优先级(一)——接口测试
    解决Jenkins可安装插件列表没有可选择插件问题
    Win10同时安装jdk1.7和jdk1.8
    Python中@staticmethod 和@classmethod 的区别
    windows下彻底删除jenkins
    selenium如何保证元素定位的成功率
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13435543.html
Copyright © 2020-2023  润新知