题解:P9869 [NOIP2023] 三值逻辑
介绍一个更加简洁易懂的并查集做法。
我们先考虑定义一个
for(int i=2;i<=n;i++) f[i]=i;
for(int i=0;i<=2*n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
char opt;cin>>opt;int x,y;
if(opt=='+') x=read()+1,y=read()+1,f[x]=f[y];
//若为 +,就令f_x=f_y
else if(opt=='-') x=read()+1,y=read()+1,f[x]=-f[y];
//若为 -,就令f_x=-f_y,意思是使f_x等于f_y的反值。
else if(opt=='T') x=read()+1,f[x]=1;
else if(opt=='F') x=read()+1,f[x]=-1;
else if(opt=='U') x=read()+1,f[x]=0;
}
处理完后
但是我们最先用对
int get(int x){
if(x<0) return n-x;
return x;
}
接着我们考虑变量
#include<bits/stdc++.h>
using namespace std;
int read(){
int f=1,k=0;char c=getchar();
while(!isdigit(c)&&c!='-') c=getchar();
if(c=='-') f=-1,c=getchar();
while(isdigit(c)) k=k*10+(c-'0'),c=getchar();
return f*k;
}
const int N=2e5+10;
int c,t,n,m,f[N],fa[N];
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
int fx=find(x),fy=find(y);
if(fx!=fy) fa[fx]=fy;
}
int get(int x){
if(x<0) return n-x;
return x;
}
int main(){
c=read(),t=read();
while(t--){
n=read()+1,m=read();int ans=0;
for(int i=2;i<=n;i++) f[i]=i;
for(int i=0;i<=2*n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
char opt;cin>>opt;int x,y;
if(opt=='+') x=read()+1,y=read()+1,f[x]=f[y];
else if(opt=='-') x=read()+1,y=read()+1,f[x]=-f[y];
else if(opt=='T') x=read()+1,f[x]=1;
else if(opt=='F') x=read()+1,f[x]=-1;
else if(opt=='U') x=read()+1,f[x]=0;
}
for(int i=2;i<=n;i++){
merge(i,get(f[i]));merge(i+n,get(-f[i]));
}
for(int i=2;i<=n;i++){
if(find(i)==find(i+n)) ans++;
}
cout<<ans<<"\n";
}
return 0;
}