zoukankan      html  css  js  c++  java
  • Luogu P1955 [NOI2015] 程序自动分析(并查集)

    廉颇老矣,尚能饭否?

    题解

      并查集动态维护,开始时所有变量构成一个集合,这里我查询了两遍。

        第一遍:处理“相等”的条件,合并两个变量所在集合。

        第二遍:处理“不等”的条件,用v数组判断,如果两个数之前都有约束过相等,再判断他们是否属于一个集合。否则不用判断,两个变量一定可以符合不等。但是要注意没约束过但i=j的情况,也是不能满足的。

      需要注意的是i和j的范围很大,首先要用离散化,把x范围映射在1-2n内,再用并查集完成。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int a[1000005][5],la[1000005],lb[1000005],fa[2000005],n,m;
    bool v[2000005];
    void lsh()     //离散化 
    {
        int i;
        sort(la+1,la+2*n+1);
        m=0;
        for(i=1;i<=2*n;i++)
            if(i==1||la[i]!=la[i-1]){m++;lb[m]=la[i];}
        for(i=1;i<=n;i++)
        {
            a[i][1]=lower_bound(lb+1,lb+m+1,a[i][1])-lb;
            a[i][2]=lower_bound(lb+1,lb+m+1,a[i][2])-lb;
        }
     } 
    int get(int x)
    {
        if(x==fa[x])return x;
        return fa[x]=get(fa[x]);
    } 
    int main()
    {
        int t,i,x,y,z,o,bj;
        scanf("%d",&t);
        while(t--)
        {
            bj=0;
            memset(a,0,sizeof(a));
            memset(la,0,sizeof(la));
            memset(lb,0,sizeof(lb));
            scanf("%d",&n);
            for(i=1;i<=n;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                if(x>y){o=x;x=y;y=o;}
                a[i][1]=x;a[i][2]=y;a[i][3]=z;
                la[2*i-1]=x;la[2*i]=y;
            }
            lsh();
            for(i=1;i<=2*n;i++)
                fa[i]=i;
            for(i=1;i<=n;i++)
            {
                if(a[i][3]==1)
                {
                    fa[get(a[i][2])]=get(a[i][1]);
                    v[a[i][1]]=1;
                    v[a[i][2]]=1;
                }
            }
            for(i=1;i<=n;i++)
            {
                if(a[i][3]==0&&a[i][1]==a[i][2])
                {
                    bj=1;
                    printf("NO
    ");
                    break;
                }
                if(a[i][3]==0&&v[a[i][1]]==1&&v[a[i][2]]==1)
                {
                    if(fa[get(a[i][1])]==fa[get(a[i][2])])
                    {
                        bj=1;
                        printf("NO
    ");
                        break;
                    }
                } 
            }
            if(bj==0)printf("YES
    ");
        }
        return 0;
     } 
  • 相关阅读:
    python 数据类型
    python核心语法
    python 基础知识
    format 用法
    有关python 函数参数
    模拟,队列与堆栈
    字符编码
    [LeetCode] Set Matrix Zeroes
    [LeetCode] Rotate Image
    [LeetCode] Unique Paths
  • 原文地址:https://www.cnblogs.com/wisdom-jie/p/14084138.html
Copyright © 2011-2022 走看看