昨晚 H wa on #3 咋回事啊
  • 板块题目总版
  • 楼主__vector__
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/5/11 09:43
  • 上次更新2024/5/11 15:24:20
查看原帖
昨晚 H wa on #3 咋回事啊
507348
__vector__楼主2024/5/11 09:43

思路是同一列,其中一个数是 −1-1,那么另外两个都是 11。
对于 1≤i≤n1 \le i \le n,ii 和 i+ni+n 分别代表 aia_i 等于 11 还是 −1-1。

同一列,每个数的 −1-1 状态向另外两个点的 11 状态连边。

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;
}

2024/5/11 09:43
加载中...