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

    Description:

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

    Analysis:

    这道题最重要的是离散化!!!
    i,j <= 10^9,不可能开这么大的数组,因此对原先的数据(book)先sort,再去重。新的数据(a)的是便是原先的数据(a)再去重后的数据(book)中的位置。即

    a[i].x = lower_bound(book,book + S,a[i].x) - book;
    a[i].y = lower_bound(book,book + S,a[i].y) - book;
    

    其实就是将原来的数映射到新数组中的位置。

    Code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 10000007
    using namespace std;
    int set[N],book[N << 1],t,tot,n;
    struct qes{
        int x,y,e;
        bool operator < (qes q) const {
            return e > q.e;
        }
    }a[N];
    int findset(int x)
    {
        if(set[x] == x) return x;
        return set[x] = findset(set[x]);
    }
    void unionset(int x,int y)
    {
        set[findset(x)] = findset(y);
    }
    void init()
    {
        memset(a,0,sizeof(a));
        memset(book,0,sizeof(book));
        memset(set,0,sizeof(set));
        tot = -1;//book从0开始
    }
    void solve(){
        sort(book,book + tot);
        int S = unique(book,book + tot) - book;
        for(int i = 1;i <= n;++i)
        {
            a[i].x = lower_bound(book,book + S,a[i].x) - book;
            a[i].y = lower_bound(book,book + S,a[i].y) - book;
        }
        sort(a + 1,a + n + 1);
        
        for(int i = 1;i <= S;++i) set[i] = i;
        
        for(int i = 1;i <= n;++i)
        {
            if(a[i].e) unionset(a[i].x,a[i].y);
            else{
            	if(findset(a[i].x) == findset(a[i].y))
            	{
                	printf("NO
    ");
                	return;
            	}	
            }
        }
        printf("YES
    "); 
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            init();
            for(int j = 1;j <= n;++j)
            {
                scanf("%d %d %d",&a[j].x,&a[j].y,&a[j].e);
                book[++tot] = a[j].x;
                book[++tot] = a[j].y;
            }
            solve();
        }
        return 0;
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    Mermaid 学习
    几个统计学的概念
    MXNet——symbol
    Graphviz 在 Windows 10 下 的 安装 Bug 解决方案
    数据挖掘学习笔记
    Python 黑魔法 --- 描述器(descriptor)
    理解 Python 中的元类
    python 创建项目
    创建 python 虚拟环境
    python开发之路Day17-算法设计(冒泡排序、选择排序、插入排序、二叉树)
  • 原文地址:https://www.cnblogs.com/Zforw/p/10883457.html
Copyright © 2011-2022 走看看