zoukankan      html  css  js  c++  java
  • BZOJ-4195 NOI2015Day1T1 程序自动分析 并查集+离散化

    总的来说,这道题水的有点莫名奇妙,不过还好一次轻松A
    4195: [Noi2015]程序自动分析
    Time Limit: 10 Sec Memory Limit: 512 MB
    Submit: 836 Solved: 361
    [Submit][Status][Discuss]

    Description
    在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。
    考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x1≠x4,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
    现在给出一些约束满足问题,请分别对它们进行判定。

    Input
    输入文件的第1行包含1个正整数t,表示需要判定的问题个数。注意这些问题之间是相互独立的。
    对于每个问题,包含若干行:
    第1行包含1个正整数n,表示该问题中需要被满足的约束条件个数。
    接下来n行,每行包括3个整数i,j,e,描述1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若e=1,则该约束条件为xi=xj;若e=0,则该约束条件为xi≠xj。

    Output
    输出文件包括t行。
    输出文件的第k行输出一个字符串“YES”或者“NO”(不包含引号,字母全部大写),“YES”表示输入中的第k个问题判定为可以被满足,“NO”表示不可被满足。

    Sample Input
    2
    2
    1 2 1
    1 2 0
    2
    1 2 1
    2 1 1

    Sample Output
    NO
    YES

    HINT
    在第一个问题中,约束条件为:x1=x2,x1≠x2。这两个约束条件互相矛盾,因此不可被同时满足。
    在第二个问题中,约束条件为:x1=x2,x2=x1。这两个约束条件是等价的,可以被同时满足。
    1≤n≤1000000
    1≤i,j≤1000000000

    本来默默的做BZOJ,旁边蛋神叫我来试试这道题,蛋哥嘲讽我的离散写的不如他的高端,于是一会我秒A,蛋哥实力调了好久,最后以奇怪的姿势A掉(一定是沙茶我看不懂),%%%,ORZ DAN

    离散化,裸并查集维护,先把x【i】=x【j】的情况合并,把x【i】!=x【j】记录下来,合并完后询问一遍有误无误即可
    

    ps:此处采用了排序后二分出位置的离散方法,或者和我蛋神一样实力%%%式离散,传送阵to DCrusher‘s blog:http://blog.csdn.net/dcrusher/article/details/50329925

    下面是代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define maxn 1000010
    struct data{
        int x,y;
    };
    int num[maxn]={0};
    int n,t;int zz;//zz==指针 
    data cx[maxn]={0};//需要查询的记录下来 
    data hb[maxn]={0};//需要合并的记录下来 
    int hbz,cxz;//记录数和查询数 
    int father[maxn]={0};//并查集 
    
    int ls()
    {
        int len;
        len=1;
        for (int i=2; i<=2*n; i++)
            if (num[i]!=num[i-1])
                num[++len]=num[i];
        return len;
    }//离散化去重 
    
    int sear(int z,int l,int r)
    {
        int mid=(l+r)>>1;
        if (z==num[mid])
            return mid;
        else if (z>num[mid])
            return sear(z,mid+1,r);
        else if (z<num[mid])
            return sear(z,l,mid);
    }//离散化二分找位置 
    
    int find(int x)
    {
        if (x==father[x])
            return x;
        father[x]=find(father[x]);
        return father[x];
    }//并查集查询 
    
    void merge(int x,int y)
    {
        int f1=find(x);
        int f2=find(y);
        if (f1!=f2)
            father[f1]=f2;
    }//并查集合并 
    
    
    int main()
    {
        scanf("%d",&t);
        while (true)
            {
                bool f=true;
                if (t==0) break;
                scanf("%d",&n);
                zz=0;hbz=0;cxz=0;
                for (int i=1; i<=n; i++)
                    {
                        int x,y,z;
                        scanf("%d%d%d",&x,&y,&z);
                        num[++zz]=x;num[++zz]=y;
                        if (z==1)
                            {hbz++;hb[hbz].x=x;hb[hbz].y=y;}
                        else
                            {cxz++;cx[cxz].x=x;cx[cxz].y=y;}
                    }//把读入的记录下来 
                sort(num+1,num+zz+1);//排序进行离散化 
                int l=ls();//离散后的长度返回回来 
                memset(father,0,sizeof(father));
                for (int i=1; i<=l; i++)
                    father[i]=i;//初始化father数组 
                for (int i=1; i<=hbz; i++)
                    {
                        int a=sear(hb[i].x,1,l);
                        int b=sear(hb[i].y,1,l);//获得离散后的值 
                        merge(a,b);
                    }//合并 
                for (int i=1; i<=cxz; i++)
                    {
                        int a=sear(cx[i].x,1,l);
                        int b=sear(cx[i].y,1,l);
                        if (find(a)==find(b))
                            {f=false;break;}
                    }//同理上述 
                if (f==true)
                    printf("YES
    ");
                else
                    printf("NO
    ");
                t--;
            }
        return 0;
    }//end。 
  • 相关阅读:
    Mysql登录错误:ERROR 1045 (28000): Plugin caching_sha2_password could not be loaded
    Docker配置LNMP环境
    Docker安装mysqli扩展和gd扩展
    Docker常用命令
    Ubuntu常用命令
    单例模式的优缺点和使用场景
    ABP 多租户数据共享
    ABP Core 后台Angular+Ng-Zorro 图片上传
    ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
    AbpCore 执行迁移文件生成数据库报错 Could not find root folder of the web project!
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346248.html
Copyright © 2011-2022 走看看