237. 程序自动分析

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

考虑一个约束满足问题的简化版本:假设 x1,x2,x3,… 代表程序中出现的变量,给定 n 个形如 xi=xj 或 xi≠xj 的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。

例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x1≠x4,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。

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

输入格式

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

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

第 1 行包含 1 个正整数 n,表示该问题中需要被满足的约束条件个数。

接下来 n 行,每行包括 3 个整数 i,j,e,描述 1 个相等/不等的约束条件,相邻整数之间用单个空格隔开。若 e=1,则该约束条件为 xi=xj;若 e=0,则该约束条件为 xi≠xj。

输出格式

输出文件包括 t 行。

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

数据范围

1≤n≤105
1≤i,j≤109

输入样例:

2
2
1 2 1
1 2 0
2
1 2 1
2 1 1

输出样例:

NO
YES

分析:

可以先把相等的用并查集归成一类,然后把不相等的作为验算,看有没有i!=j,但fa[i]==fa[j]的,有的话就输出no;还有一个比较重要的是,i和j的值达到了1e9,因此需要离散化处理,我用了vector数组来离散化。

 代码如下:

#include 

using namespace std;
const int N=1e5+10;
int fa[2*N],x1[N],x2[N],e[N];
vectoran,a1;
int t,n;

int find(int x)
{
    if(fa[x]!=x) fa[x]=find(fa[x]);
    //cout<>t;
    while(t--)
    {
        cin>>n;
        
        int flag=1;
        an.clear(),a1.clear();
        for(int i=1;i<=n;i++)
        {
            cin>>x1[i]>>x2[i]>>e[i];
            an.push_back(x1[i]);
            an.push_back(x2[i]);
        }
        sort(an.begin(),an.end());
     
        for(int i=0;i<2*n;i++)
        {

            if(i&&an[i]==an[i-1])continue;
            else a1.push_back(an[i]);
        }
        for(int i=1;i<=an.size();i++)fa[i]=i;
        for(int i=1;i<=n;i++)
        {
            if(!e[i]) continue;
            int xx=find(findid(x1[i]));
            int yy=find(findid(x2[i]));
            fa[xx]=yy;
        }
        for(int i=1;i<=n;i++)
        {
            if(e[i])continue;
            int xx=find(findid(x1[i]));
            int yy=find(findid(x2[i]));
            if(xx==yy)
            {
                flag=0;
                break;
            }
        }
        if(flag)cout<<"YES"<

你可能感兴趣的:(数据结构进阶,笔记,c++,并查集,离散化)