离散化 + 并查集 I - Invoking the Magic Gym - 102770I

unique函数

需要认识一个新的函数:unique函数
unique函数可以删除有序数组中的重复元素。
注意:
a 这里的删除不是真的delete,而是将重复的元素放到容器末尾
b unique函数的返回值是去重之后的尾地址
c 一定要先对数组进行排序才可以使用unique函数

unique(s, s + tot)

与大多数函数一样,两个参数是数组的地址,前闭后开,返回值是迭代器。

另一道离散化题

I - Invoking the Magic Gym - 102770I

在这里插入图片描述
分析:
读完题应该可以想到并查集,维护每个集合元素个数。
看了数据范围应该能想到离散化。
离散化过程:
先按照输入顺序,把数据存在另一个数组中,然后排序,在去重,去重用到上面说的unique函数,这样离散化数组s[i]就预处理好了。(然后这个一开始构造的时候还是习惯性的不用s[0],然后就wa了,改成从0开始用就A了)
接下来遍历每一对袜子,对每一只袜子需要在离散化数组中二分查找,我们它们在离散化数组中的下标来代替它,查到之后就是并查集惹。
AC代码:

#include <bits/stdc++.h>

using namespace std;

int fa[1000050];
int sum[1000050];
int a[1000050];
int b[1000050];
int s[1000050];
int tot, ans, t, n;
int fx, fy;
int u, v;

int findfa(int x)
{
    return x == fa[x] ? x : fa[x] = findfa(fa[x]);
}

void merge_(int x, int y)
{
    fx = findfa(x);
    fy = findfa(y);
    fa[fy] = fx;
    sum[fx] += sum[fy];
    ans = max(ans, sum[fx]);
}

int main()
{
    scanf("%d", &t);
    while(t--)
    {
        ans = 0;
        tot = 0;
        scanf("%d", &n);
        for(int i = 0; i < n; ++i)
        {
            scanf("%d%d", &a[i], &b[i]);
            s[tot++] = a[i];
            s[tot++] = b[i];
        }
        sort(s, s + tot);
        tot = unique(s, s + tot) - s;
        for(int i = 0; i <= tot; ++i)
        {
            fa[i] = i;
            sum[i] = 1;
        }
        for(int i = 0; i < n; ++i)
        {
            u = lower_bound(s, s + tot, a[i]) - s;
            v = lower_bound(s, s + tot, b[i]) - s;
            if(findfa(u) != findfa(v)) merge_(u, v);
        }
        printf("%d\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值