链接:https://ac.nowcoder.com/acm/contest/1031/A
来源:牛客网
题目描述
在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。
考虑一个约束满足问题的简化版本:假设 ?1, ?2, ?3, ⋯ 代表程序中出现的变量,给定 ? 个形如 ?? = ?? 或 ?? ≠ ?? 的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为: ?1 = ?2, ?2 = ?3, ?3 = ?4, ?1 ≠ ?4 ,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
现在给出一些约束满足问题,请分别对它们进行判定。
输入描述
第1行包含1个正整数t,表示需要判定的问题个数。注意这些问题之间是相互独立的。
对于每个问题,包含若干行:
第1行包含1个正整数n,表示该问题中需要被满足的约束条件个数。
接下来n行,每行包括3个整数i,j,e,描述1个相等/不等的约束条件,相邻整数之间用单个空格隔开。若e=1,则该约束条件为xi=xj;若e=0,则该约束条件为xi≠xj。
输出描述
包括t行。
第k行输出一个字符串“YES”或者“NO”(不包含引号,字母全部大写),“YES”表示输入中的第k个问题判定为可以被满足,“NO”表示不可被满足。
题解:离散化+并查集
将所有相等的合并成一个集合,然后对不相等的进行查询是否在一个集合,在一个集合则矛盾。但是数据范围比较大,需要离散化。O( nlog(n) )
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IOS ios::sync_with_stdio(false)
#define maxn 200005
#define inf 1000000009
int ff[maxn];
int find(int x)
{
return ff[x]==x?x:ff[x]=find(ff[x]);
}
struct node
{
int x,y,z;
};
int main()
{
IOS;
int T;
cin>>T;
while(T--)
{
vector<node>V;
map<int,int>M;
int n;
cin>>n;
for(int i=0; i<maxn; i++)
ff[i]=i;
int k=1;
for(int i=0; i<n; i++)
{
int x,y,z;
cin>>x>>y>>z;
V.push_back(node{x,y,z});
if(M.find(x)==M.end())
M[x]=k++;
if(M.find(y)==M.end())
M[y]=k++;
}
for(int i=0; i<V.size(); i++)
{
int x=V[i].x,y=V[i].y,z=V[i].z;
if(z==0)continue;
int x1=M[x],y1=M[y];
int nx=find(x1),ny=find(y1);
if(nx!=ny)
ff[nx]=ny;
}
bool flag=true;
for(int i=0; i<V.size(); i++)
{
int x=V[i].x,y=V[i].y,z=V[i].z;
if(z==1)continue;
int x1=M[x],y1=M[y];
int nx=find(x1),ny=find(y1);
if(nx==ny)
{
flag=false;
break;
}
}
if(flag)
cout<<"YES"<<"\n";
else
cout<<"NO"<<"\n";
}
return 0;
}