zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第八场)I题Interesting Computer Game(并查集)

    2020牛客暑期多校训练营(第八场)I题Interesting Computer Game(并查集)

    Interesting Computer Game

    题意:给n个数的a,b,对于每个i可取a[i]或b[i]或不取,输出最大取出的数的集合大小。

    题解:这题有点像一个dp题,想了几分钟dp,发现是不可d的,那就找规律呗,如{1 2},{2 3}答案是2,{1 2},{2 3},{3 1}答案是3,我们发现1->2->3这种只能取3减一,但它成环则可以取3,所以只要判断所有连通块是否成环与计算其大小,并查集乱搞既可。

    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    int t,n,u[100007],v[100007],b[200007];
    int fa[200007],ok[200007],siz[200007];
    int fin(int p){
    	if(fa[p]==p)return p;
    	else{
    		return fa[p]=fin(fa[p]);
    	}
    }
    
    int main(){
    	int o=0;
    	scanf("%d",&t);
    	while(t--){
    		o++;
    		scanf("%d",&n);
    		int m=0;
    		for(int i=1;i<=n;i++){
    			scanf("%d%d",&u[i],&v[i]);
    			b[++m]=u[i];
    			b[++m]=v[i];
    		}
    		sort(b+1,b+1+m);
    		m=unique(b+1,b+1+m)-b-1;
    		for(int i=1;i<=n;++i){
    			u[i]=lower_bound(b+1,b+1+m,u[i])-b;
    			v[i]=lower_bound(b+1,b+1+m,v[i])-b;
    		}
    		for(int i=1;i<=m;i++){
    			fa[i]=i;
    			ok[i]=0;
    			siz[i]=1;
    		}
    		for(int i=1;i<=n;i++){
    			int f1=fin(u[i]);
    			int f2=fin(v[i]);
    			if(f1==f2){
    				ok[f1]=1;
    			}
    			else{
    				fa[f1]=f2;
    				ok[f2]=ok[f1]=max(ok[f2],ok[f1]);
    				siz[f2]+=siz[f1];
    			}
    		}
    		int ans=0;
    		for(int i=1;i<=m;i++){
    			if(fin(i)!=i)continue;
    			ans+=siz[fin(i)]-1;
    			if(ok[fin(i)])ans++;
    		}
    		printf("Case #%d: %d
    ",o,ans);
    	}
    }
    
    
  • 相关阅读:
    句柄
    类,方法,抽象方法,接口
    Enum类型
    String 为什么是不可变的
    大数据怎么排序
    oracle创建表空间 导入数据库
    eclipse常见小问题
    eclipse创建项目
    存储过程
    在VMware通过挂载系统光盘搭建本地yum仓库
  • 原文地址:https://www.cnblogs.com/whitelily/p/13429910.html
Copyright © 2011-2022 走看看