2-SAT模版

复杂度 O ( n + m ) O(n+m) O(n+m)

原理证明 侵删

爆搜模版在这里 侵删

const int maxn = 2e6+1000;

vector g[maxn];
int low[maxn],dfn[maxn];
int scc[maxn];
int sta[maxn];
bool vis[maxn];
int num=0,ind=0;
int cnt=0;

int n,p,M,m;
int tol;

int fid(int x){
	return p+x;
}

int yid(int x){
	return 2*x-1;
}

int nid(int x){
	return 2*x;
}

void tarjan(int u){
	vis[u]=1;
	dfn[u]=low[u]=++num;
	sta[++ind]=u;
	for(auto i:g[u]){
		if(!dfn[i]){
			tarjan(i);
			low[u]=min(low[u],low[i]);
		}else if(vis[i]){
			low[u]=min(low[u],low[i]);
		}
	}
	if(dfn[u]==low[u]){
		++cnt;
		do{
			vis[sta[ind]]=0;
			scc[sta[ind]]=cnt;
			--ind;
		}while(u!=sta[ind+1]);
	}
}

int ans[maxn];
int f;

void _2sat(){
	tol=(p+M)*2;
	for(int i=1;i<=tol;++i){
		if(!dfn[i]){
			tarjan(i);
		}
	}
	int ft=0;
	for(int i=1;i<=p;++i){
		int yx=yid(i),nx=nid(i);
		if(scc[yx]==scc[nx]) {
			cout<<-1<

你可能感兴趣的:(模版)