题意: 考虑一个约束满足问题:假设x1,x2,x3…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。
分析: 给出的约束条件一共有两种:
1.xi=xj
2.xi!=xj
可以发现,对于每一种条件,他们之间是不会相互冲突的
那么,不同时满足这两种条件,当且仅当一类条件全部满足时,另外一类条件至少有一条与前面相违背。
这样,我们就可以将第一种约束条件放在一起,再一个个的去查询看是否第二种条件每个都满足
具体用并查集实现即可
那为啥要用HASH呢?
注意看数据范围:1≤n≤100000,1≤i,j≤1000,000,000
直接用数组存的话肯定爆炸
但是我们发现其实i,j的具体取值并没有什么卵用,所以我们直接把它映射到哈希表上用就可以了
P.S:之前用的哈希函数老是挂,找了一下午没找出原因,结果把mod的值改了一下竟然A了?好吧,还是老老实实双函数吧!
详细代码如下:
#include <bits/stdc++.h>
using namespace std;
const int mod=400003;
long long fa[mod],w1[100001],w2[100001],num[mod];
bool vis[mod];
int tot=0;
long long read() {
long long ans=0,flag=1;
char ch=getchar();
while( (ch<'0' || ch>'9') && ch!='-' ) ch=getchar();
if(ch=='-') flag=-1,ch=getchar();
while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar();
return ans*flag;
}
int find(int x) {
if(x!=fa[x]) {
fa[x]=find(fa[x]);
}
return fa[x];
}
void merge(int x,int y) {
int fx=find(x),fy=find(y);
if(fx!=fy) {
fa[fx]=fy;
}
return ;
}
long long g(long long x) {
return (x+463)%mod;
}
int main() {
int t=read();
long long a,b,c,x,y,m;
while(t--) {
tot=0;
memset(vis,0,sizeof(vis));
for(int i=0;i<mod;i++) fa[i]=i;
m=read();
for(long long i=1;i<=m;i++) {
a=read(),b=read(),c=read();
x=a%mod;y=b%mod;
while(1) {
if(!vis[x]) {
vis[x]=true;
num[x]=a;
break;
}else if(num[x]==a) {
break;
}else {
x=g(x);
}
}
while(1){
if(!vis[y]) {
vis[y]=true;
num[y]=b;
break;
}else if(num[y]==b){
break;
}else {
y=g(y);
}
}
if(c) {
merge(x,y);
}else {
tot++;
w1[tot]=x;
w2[tot]=y;
}
}
bool flag=0;
for(int i=1;i<=tot;i++) {
if(find(w1[i])==find(w2[i])) {
flag=1;
break;
}
}
if(flag) {
printf("NO\n");
}else {
printf("YES\n");
}
}
return 0;
}
by:Chlience