zoukankan      html  css  js  c++  java
  • 洛谷 P1955 [NOI2015] 程序自动分析

    https://www.luogu.com.cn/problem/P1955

    题目描述

    在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。

    考虑一个约束满足问题的简化版本:假设x1,x2,x3,⋯ 代表程序中出现的变量,给定 n 个形如xi=xj 或 xi=xj 的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x_1=x_2,x_2=x_3,x_3=x_4,x_4\neq x_1x1=x2,x2=x3,x3=x4,x4=x1,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。

    现在给出一些约束满足问题,请分别对它们进行判定。

    输入格式

    输入的第一行包含一个正整数 t,表示需要判定的问题个数。注意这些问题之间是相互独立的。

    对于每个问题,包含若干行:

    第一行包含一个正整数 n,表示该问题中需要被满足的约束条件个数。接下来 n 行,每行包括三个整数 i,j,e,描述一个相等/不等的约束条件,相邻整数之间用单个空格隔开。若 e=1,则该约束条件为 xi=xj。若e=0,则该约束条件为 xi=xj

    输出格式

    输出包括 t 行。

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

    输入输出样例

    输入 #1
    2
    2
    1 2 1
    1 2 0
    2
    1 2 1
    2 1 1
    输出 #1
    NO
    YES
    
    输入 #2
    2
    3
    1 2 1
    2 3 1
    3 1 1
    4
    1 2 1
    2 3 1
    3 4 1
    1 4 0
    
    输出 #2
    YES
    NO

    说明/提示

    注:实际上 n10^6 。

    分析

    除开离散化的话算是裸的并查集,写的时候感觉细节还是蛮多的。 涉及了关于unique在vector的用法

    代码

    //最多只有2n个数,考虑离散化
    //离线操作 
    
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e6+5;
    int p[N*2];
    vector<int> book;//用于离散化操作
    
    struct Hd
    {
        int a;
        int b;
        int e;
    };
    
    Hd hd[N*2];
    
    bool cmp(Hd &n,Hd &m)
    {
        return n.e>m.e;
    }//优先合并操作 
    
    int discre(int num)//查询离散化结果 
    {
        return lower_bound(book.begin(),book.end(),num)-book.begin()+1;//+1,vecor从0开始,而p从1开始 
    }
     
    
    //并查集板子
    
    int getf(int num_a)
    {
        if(num_a==p[num_a]) return num_a;
        else return p[num_a]=getf(p[num_a]);
    }
    
    void mer(int j,int k)
    {
        int jf=getf(j);
        int kf=getf(k);
        if(jf!=kf)
        {
            p[kf]=jf;
        }
    }
    
    bool my_unique(int j,int k)
    {
        return j==k;//定义去重规则 
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(p,0,sizeof(p));
            book.clear();
            int n;
            cin>>n;
            for(int i=1;i<=n;i++)
            {
                cin>>hd[i].a>>hd[i].b>>hd[i].e;
                book.push_back(hd[i].a);
                book.push_back(hd[i].b);
            }
            
            for(int i=1;i<=n*2;i++)
            {
                p[i]=i;//细节,并查集要初始化到2n 
            }
            
            sort(hd+1,hd+n+1,cmp);//优先合并操作 
            
            sort(book.begin(),book.end());//排序 离散表 
            
            vector<int>::iterator it;
            
            it=unique(book.begin(),book.end(),my_unique);//去重 
            
            book.erase(it,book.end());
            //vector去重过程 
            
            int fl=true;
            for(int i=1;i<=n;i++)
            {
                if(hd[i].e==1)
                {
                    mer(discre(hd[i].a),discre(hd[i].b));
                }
                else
                {
                    if(getf(discre(hd[i].a))==getf(discre(hd[i].b)))
                    {
                        fl=false;
                    }
                }
            }
            
            if(fl==true) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    inputstream和outputstream读写数据模板代码
    如何显示包的上一层包
    我的cnblogs设置代码
    myeclipse ctrl+shift+F失效
    数据包加密解密
    用VisualSVN Server创建版本库,以及TortoiseSVN的使用
    权限验证MVC
    Asp.net MVC23 使用Areas功能的常见错误
    MVC基础知识
    最全的Resharper快捷键汇总
  • 原文地址:https://www.cnblogs.com/KyleDeng/p/15646493.html
Copyright © 2011-2022 走看看