思路是同一列,其中一个数是 −1,那么另外两个都是 1。
对于 1≤i≤n,i 和 i+n 分别代表 ai 等于 1 还是 −1。
同一列,每个数的 −1 状态向另外两个点的 1 状态连边。
2sat 求出方案后再验证一遍。
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define REP(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
#define mkpr make_pair
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<class T>
void ckmx(T& a,T b){
a=max(a,b);
}
template<class T>
void ckmn(T& a,T b){
a=min(a,b);
}
int T;
const int maxn=1005;
int n;
int g[maxn][5];
vector<int> gp[maxn*2];
int get(int x,int sz){
// 编号是 x,它值是 sz 对应状态
if(x<0){
sz=-sz;
x=-x;
}
if(sz==-1){
return x+n;
}else{
return x;
}
}
int dfn[maxn*2],low[maxn*2];
bool ins[maxn*2];
int stk[maxn*2],top;
int dfncnt;
int color[maxn*2];
int scccnt=0;
void clear(){
FOR(i,0,n*2){
// printf("i = %d\n",i);
gp[i].clear();
// puts("???");
dfn[i]=low[i]=0;
ins[i]=0;
color[i]=0;
}
scccnt=0;
top=0;
dfncnt=0;
}
void tarjan(int u,int _fa){
dfn[u]=low[u]=++dfncnt;
// printf("u = %d\n",u);
ins[u]=1;
stk[++top]=u;
for(int& v:gp[u]){
if(v!=_fa){
// printf("v = %d\n",v);
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
}else if(ins[v]){
low[u]=min(low[u],dfn[v]);
}
}
}
if(dfn[u]==low[u]){
scccnt++;
while(stk[top]!=u){
ins[stk[top]]=0;
color[stk[top]]=scccnt;
top--;
}
color[u]=scccnt;
ins[u]=0;
top--;
}
}
int a[maxn];
void solve(){
scanf("%d",&n);
FOR(i,1,3){
FOR(j,1,n){
scanf("%d",&g[j][i]);
}
}
FOR(i,1,n){
gp[get(g[i][1],-1)].emplace_back(get(g[i][2],1));
gp[get(g[i][1],-1)].emplace_back(get(g[i][3],1));
gp[get(g[i][2],-1)].emplace_back(get(g[i][1],1));
gp[get(g[i][2],-1)].emplace_back(get(g[i][3],1));
gp[get(g[i][3],-1)].emplace_back(get(g[i][1],1));
gp[get(g[i][3],-1)].emplace_back(get(g[i][2],1));
}
FOR(i,1,2*n){
if(!dfn[i]){
tarjan(i,0);
}
}
FOR(i,1,n){
// printf("color[%d] = %d color[%d] = %d\n",i,color[i],i+n,color[i+n]);
if(color[i]==color[i+n]){
puts("NO");
clear();
return;
}
}
FOR(i,1,n){
if(color[i]<color[i+n]){
a[i]=1;
}else{
a[i]=-1;
}
}
FOR(i,1,n){
FOR(j,1,3){
if(g[i][j]<0){
g[i][j]=-a[-g[i][j]];
}else{
g[i][j]=a[g[i][j]];
}
}
sort(g[i]+1,g[i]+4);
if(g[i][2]!=1){
puts("NO");
clear();
return;
}
}
puts("YES");
clear();
return;
}
int main()
{
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}