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\n");
            	return;
        	}	
        }
    }
    printf("YES\n"); 
}
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;
}
posted @ 2019-05-17 20:16  Zforw  阅读(18)  评论(0编辑  收藏  举报