zoukankan      html  css  js  c++  java
  • 51nod 1515 明辨是非

    题目描述:

    给$n$组操作,每组操作形式为 x y p。
    当$p$为 1 时,如果第$x$变量和第$y$个变量可以相等,则输出YES,并限制他们
    相等;否则输出 NO,并忽略此次操作。
    当$p$为 0 时,如果第$x$变量和第$y$个变量可以相等,则输出 YES,并限制他
    们相等;否则输出 NO,并忽略此次操作。

    思路:

    看到维护相等关系,自然的想到并查集。

    但是本题要维护相等和不等关系,普通的并查集无法满足。

    之后怎么办呢?在考场的我就懵逼了。后来发现用set暴力维护每个并查集内不能和谁相等就完了。好弱智啊!我果然还是太菜了。

    在合并相等关系时可以找到元素个数较少的一个set,将他直接插进另一个set里。这种暴力被称为启发式合并。奇技淫巧

    合并不等关系时直接加入set里就好了。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<set>
    #include<map>
    using namespace std;
    set<int>s[2000005];
    set<int>::iterator it;
    map<int,int>a;
    int f[2000005];
    int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
    int main()
    {
    //    freopen("TrueFalse.in","r",stdin);
    //    freopen("TrueFalse.out","w",stdout);
        int n;
        scanf("%d",&n);
        int i,cnt=0;
        for(i=1;i<=n*2;i++)
            f[i]=i;
        for(i=1;i<=n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x]?(x=a[x]):(x=a[x]=++cnt);
            a[y]?(y=a[y]):(y=a[y]=++cnt);
            int opt;
            scanf("%d",&opt);
            int u=find(x);
            int v=find(y);
            if(opt==1)
            {
                if(s[u].count(v))
                    puts("NO");
                else if(u!=v)
                {
                    if(s[u].size()>s[v].size())
                        swap(u,v);
                    f[u]=v;
                    for(it=s[u].begin();it!=s[u].end();it++)
                    {
                        s[*it].erase(u);
                        s[*it].insert(v);
                        s[v].insert(*it);
                    }
                    puts("YES");
                }
                else
                    puts("YES");
            }
            else
            {
                if(u==v)
                    puts("NO");
                else
                {
                    s[u].insert(v);
                    s[v].insert(u);
                    puts("YES");
                }
            }
        }
    }
  • 相关阅读:
    java 之 xml
    oracle 之 定时任务,存储过程和游标等语法案例
    oracle 之创建定时器
    java 之 音乐播放代码
    oracle函数之 minus
    iis默认文档有什么用?
    html页面使用前端框架布局时,弹出子页面等情况若出现布局混乱,可能是回发导致
    html 之 区块元素属性(待补充)
    EffectiveJava(2)应对多个构造函数应当使用构建器
    EffectiveJava(1) 构造器和静态工厂方法
  • 原文地址:https://www.cnblogs.com/handsome-wjc/p/11291247.html
Copyright © 2011-2022 走看看