I Interesting Computer Game(并查集)

I Interesting Computer Game

题目传送门

Interesting Computer Game

思路

将每次输入的a和b当做点,将其连成一条边,很明显的对于形成的连通块来说,如果无环就只能取到当前连通块的顶点减一的点,如果连通块内存在至少一个环,即可将该连通块取完,所以我们只需要判断连通块有无环
同时我们注意到数据的范围为 1 a i 1 0 9 1 \le a_i \le 10^9 1 b i 1 0 9 1 \le b_i \le 10^9
所以要采取离散化的方法将数据处理一下,然后对于连通块采取并查集的方式进行维护

AC Code

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5 +9;
// #define TDS_ACM_LOCAL
int n, vis[N<<1], ls[N<<1], fa[N<<1];
int x, y, len, cnt, ans, idx;
pair<int,int>p[N];

int find(int x){                //查找并查集的祖先
    if(x==fa[x])    return x;
    return fa[x]=find(fa[x]);
}

void solve(){
    cin>>n;
    len=0;
    for(int i=1; i<=n; i++){
        cin>>p[i].first>>p[i].second;
        ls[++len]=p[i].first, ls[++len]=p[i].second;    //ls离散化数组
    }
    sort(ls+1, ls+1+len);                               //排序
    cnt=unique(ls+1, ls+1+len)-ls-1;                    //去重并且求得不同元素的个数
    for(int i=1; i<=cnt; i++) fa[i]=i, vis[i]=0;
    for(int i=1; i<=n; i++){                            
        p[i].first=lower_bound(ls+1, ls+1+cnt, p[i].first)-ls;      //更新原数组的元素
        p[i].second=lower_bound(ls+1, ls+1+cnt, p[i].second)-ls;
        x=find(p[i].first), y=find(p[i].second);                    //找到相应的祖先
        if(x!=y){
            fa[y]=x;
            if(vis[x] || vis[y])    vis[x]=1, vis[y]=0;             //当有环的连通块遇到其他的连通块时,将祖先标记为1
        }
        else    vis[x]=1;                                           //相同祖先结点即为在一个连通块,即为行成环
    }
    ans=cnt;    //ans先取最大(即为a和b中不同元素的个数)
    for(int i=1; i<=cnt; i++) if(fa[i]==i && !vis[i]) ans--;        //如果为祖先但是为0(即为无环),ans--
    cout<<"Case #"<<++idx<<": "<<ans<<endl;
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xmyrzb/article/details/107804352