首页 > 其他 > 详细

I Interesting Computer Game(取绑定点对中的一个,问最多能取多少不同的数,并查集判环)

时间:2020-08-04 13:53:11      阅读:85      评论:0      收藏:0      [点我收藏+]

题:https://ac.nowcoder.com/acm/contest/5673/I

题意:给定n对点对,每次只能从点对中取出之前没有取过的点,问最多能取到多少个不同的点。

分析:将点设为图上的点,点对即为边,离散化一下数据总共的点数为m,对于图的一个连通分量,假设它的大小为x,那么若这个连通分量有环则所有数都可以取到(贡献为x),若只是一个树形结构,则对答案的贡献为x-1。

   用并查集判一下有无环即可。

技术分享图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int M=2e5+5;
const int mod=998244353;
int f[M],a[M],b[M],vis[M],tmp[M];
int Find(int x){return x==f[x]?x:f[x]=Find(f[x]);}
int main(){
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        int n;
        scanf("%d",&n);

        for(int u,v,i=1;i<=n;i++){
            scanf("%d%d",&a[i],&b[i]);
            tmp[i]=a[i],tmp[i+n]=b[i];
        }
        sort(tmp+1,tmp+1+2*n);
        int m=unique(tmp+1,tmp+1+2*n)-tmp-1;
        for(int i=1;i<=m;i++)
            f[i]=i,vis[i]=0;

        for(int i=1;i<=n;i++){
            int x=lower_bound(tmp+1,tmp+1+m,a[i])-tmp;
            int y=lower_bound(tmp+1,tmp+1+m,b[i])-tmp;
            int u=Find(x),v=Find(y);
            if(u==v){
                vis[u]=1;
                continue;
            }
            f[u]=v;
            if(vis[u])vis[v]=1;
        }
        int ans=m;
        for(int i=1;i<=m;i++)
            if(f[i]==i&&!vis[i])
                ans--;
        printf("Case #%d: %d\n",cas,ans);
    }
    return 0;
}
View Code

 

I Interesting Computer Game(取绑定点对中的一个,问最多能取多少不同的数,并查集判环)

原文:https://www.cnblogs.com/starve/p/13432600.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!