集合问题 并查集

集合问题

https://ac.nowcoder.com/acm/problem/15167

首先知道p[i]≥1,所以不存在p[i]大于等于max(a,b)
用map<ll,ll>mp记录下每个p[i]出现的下标,每次找到b-p[i]或a-p[i]都进行一次连接
因为考虑优先放入到b中,所以在YES的前提下,if判断是否放在b的条件放在前面。
需要注意的输出格式问题,就是最后没有多余的空格,当时我傻了挺久的才发现这个。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
ll pre[100005],p[100005];
void init(ll n)
{
    for(ll i=0;i<=n+1;i++)
        pre[i]=i;
}
ll Find(ll x)
{
    return pre[x]==x?x:pre[x]=Find(pre[x]);
}
void mix(ll a,ll b)
{
    ll fa=Find(a),fb=Find(b);
    if(fa!=fb){
        pre[fa]=fb;
    }
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    ll n,a,b,mx=0;cin>>n>>a>>b;
    init(n);
    map<ll,ll>mp;
    for(ll i=1;i<=n;i++)
    {
        cin>>p[i];
        mp[p[i]]=i;
        mx=max(mx,p[i]);
    }
    if(mx>=max(a,b)){
        cout<<"NO";return 0;
    }
    for(ll i=1;i<=n;i++)
    {
        if(mp[b-p[i]]){
            mix(i,mp[b-p[i]]);
        }
        else mix(i,0);
        if(mp[a-p[i]]){
            mix(i,mp[a-p[i]]);
        }
        else mix(i,n+1);
    }
    ll numa = Find(0);
        ll numb = Find(n+1);
    if(numa==numb){
        cout<<"NO";
    }
    else {

        cout<<"YES"<<endl;
        for(ll i=1;i<=n;i++)
        {
            if(numa==Find(i)){
                cout<<0;
            }
            else cout<<1;
            if(i!=n)
            cout<<" ";
        }
    }

}
全部评论
输入4 5 9 2 3 3 6的时候好像不太对啊大佬
点赞 回复 分享
发布于 2022-03-28 21:13

相关推荐

05-29 20:34
门头沟学院 C++
KarlAllen:得做好直接春招的准备。学历差的话,一是面试要求会比学历好的严格不少,二是就算面试通过了也会被排序。总之暑期和秋招对于学历差的就是及其不友好
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务