hdu 1856 并查集

题意:给你一些关系,问你在最多有多少人在一个关系中,经我们学长讲解后,知道了离散化这种方法,因为: 点数最多为10^7,但是边数最多10^5,其实这就有点类似与哈希表的思想,我们将所有的点存在数组里,然后在排序,去重,之后就可以一一对应fa[]数组的下标了(也就是它排第几个)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 200010;

struct Node
{
    int x,y;
};
Node node[MAXN];
int n,pos;
int num[MAXN];
int fa[MAXN];
int rank[MAXN];

void init()
{
    sort(num,num+pos);
    pos = unique(num,num+pos) - num;
    for (int i = 0; i <= pos; i++)
    {
        fa[i] = i;
        rank[i] = 1;
    }
}

int search(int x)
{
    int left = 0;
    int right = pos - 1;
    while (left <= right)
    {
        int mid = (left + right)>>1;
        if (num[mid] == x)
            return mid+1;   // 数组的第几个,从下标1开始
        else if (num[mid] < x)
            left = mid + 1;
        else right = mid - 1;
    }
}

int find(int x)
{
    if (fa[x] != x)
        fa[x] = find(fa[x]);
    return fa[x];
}
int solve()
{
    init();
    int ans = 0;
    for (int i = 0; i < n; i++)
    {
        int x = search(node[i].x);
        int y = search(node[i].y);
        int fx = find(x);
        int fy = find(y);
        if (fx != fy)
        {
            fa[fx] = fy;
            rank[fy] += rank[fx];
            ans = max(ans,rank[fy]);
        }
    }
    return n == 0 ? 1 : ans;
}
int main()
{
    while (scanf("%d",&n) != EOF)
    {
        pos = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d",&node[i].x,&node[i].y);
            num[pos++] = node[i].x;
            num[pos++] = node[i].y;
        }
        
        printf("%d\n",solve());
    }
    return 0;
}


你可能感兴趣的:(hdu 1856 并查集)