51Nod 1515(并查集set离散化)

Posted west__wind

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod 1515(并查集set离散化)相关的知识,希望对你有一定的参考价值。

//代码还是YY学姐帮改的,自己从来没有真正A过几道题,不是看题解就是有BUG找不出,多久了还是改变不了这样的现状,或许ACM就是这么筛选人的吧。从5.24到11.24,再到又一年的5.24,可感觉后者比前者过得快多了。多读了一年的大学,完全没有了时间概念,不知道现在到底是大几了,不知道现在到底处在什么位置,不知道毕业后到底从不从事IT这行,一切都是未知的。

 

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1515

思路:数字范围为1e8,所以要先离散化,然后在每个连通块的祖先节点用一个set维护,两个联通块合并的时候对set作恰当处理。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
int father[N],r[N];
map <int,int> vis;
set <int> s[N];
set <int> :: iterator it;
struct node
{
    int x,y,p;
}q[N>>1];
int finds(int x)
{
    if(father[x] != x)
        father[x] = finds(father[x]);
    return father[x];
}
void connect(int a,int b)
{
    if(r[a] > r[b])
    {
        for(it = s[b].begin(); it != s[b].end(); it++)
        {
            int tmp = finds(*it);
            s[*it].erase(b);
            s[a].insert(tmp);
            s[tmp].insert(a);
        }
        father[b] = a;
        r[a]++;
    }
    else
    {
        for(it = s[a].begin(); it != s[a].end(); it++)
        {
            int tmp = finds(*it);
            s[*it].erase(a);
            s[b].insert(tmp);
            s[tmp].insert(b);
        }
        father[a] = b;
        r[b]++;
    }
}
int main()
{
    int n,x,y,t = 1;
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d %d %d",&x,&y,&q[i].p);

        if(!vis[x])
        {
            vis[x] = t;
            q[i].x = t++;
        }
        else
            q[i].x = vis[x];

        if(!vis[y])
        {
            vis[y] = t;
            q[i].y = t++;
        }
        else
            q[i].y = vis[y];
    }

    for(int i = 1; i <= n; i++)
    {
        father[q[i].x] = q[i].x;
        father[q[i].y] = q[i].y;
    }

    for(int i = 1; i <= n; i++)
    {
        t = 0;
        x = finds(q[i].x);
        y = finds(q[i].y);
        if(q[i].p)
        {
            if(x == y)
                puts("YES");
            else
            {
                if(s[x].count(y))
                    puts("NO");
                else
                {
                    puts("YES");
                    connect(x,y);
                }
            }
        }
        else
        {
            if(x == y)
                puts("NO");
            else
            {
                puts("YES");
                s[x].insert(y);
                s[y].insert(x);
            }
        }
    }
    return 0;
}

 

以上是关于51Nod 1515(并查集set离散化)的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1515 明辨是非 [并查集+set]

51nod 1515 明辨是非 并查集 + set + 启发式合并

51nod-1515 明辨是非——并查集

[題解]51nod_1515_明辨是非

51nod-1366 贫富差距——并查集

51nod 1307 绳子与重物(并查集水了一发)