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);
    	}
    }
    
    
  • 相关阅读:
    熟悉常用的HBase操作
    爬虫大作业
    熟悉常用的HDFS操作
    数据结构化与保存
    获取全部校园新闻
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离+网络爬虫基础练习
    中文词频统计
    英语词频统计
    AXIOS中文文档
    overload方法重载
  • 原文地址:https://www.cnblogs.com/whitelily/p/13429910.html
Copyright © 2011-2022 走看看