LuoguP4782 【模板】2-SAT 问题 (2-SAT)

Not difficult, the only problem is how to deal with give 0/1 to the var.
Tarjan offers the reverse topological order. For each connected, the earlier one in the order ought to be 0.//I'm not sure, for truth.

int dfn[N],dfnIndex,low[N],vis[N];
int sta[N],top;
int scc[N],sccIndex;
inline void Tarjan(int u){
	dfn[u] = low[u] = ++dfnIndex;
	sta[++top] = u;
	vis[u] = true;
	for(register int i = head[u]; i; i = e[i].nxt){
		int v = e[i].pre;
		if(!dfn[v]){
			Tarjan(v);
			low[u] = Min(low[u], low[v]);
		}
		else if(vis[v]){
			low[u] = Min(low[u], dfn[v]);//letter
		}
	}
	if(dfn[u] == low[u]){
		++sccIndex;
		do{
			scc[sta[top]] = sccIndex;
			vis[sta[top]] = false;
		}while(sta[top--] != u);
	}
}

inline bool Judge(){
	R(i,1,n){
		if(scc[i<<1] == scc[i<<1|1])
			return false;
	}
	return true;
}

int main(){
	int m;
	io >> n >> m;
	R(i,1,m){
		int a,b,c,d;
		io >> a >> b >> c >> d;
		add(a << 1 | (b ^ 1), c << 1 | d);
		add(c << 1 | (d ^ 1), a << 1 | b);
	}
	
	n = n << 1 | 1;
	R(i,2,n){
		if(!dfn[i])
			Tarjan(i);
	}
	n = (n - 1) >> 1;
	
	if(Judge() == true){
		printf("POSSIBLE\n");
	}
	else{
		printf("IMPOSSIBLE\n");
		return 0;
	}
	
	R(i,1,n){
		//if bool varible x appears earlier than -x, let it be false//alright, ignore this, I haven't understand it yet.
		printf("%d ", scc[i<<1] > scc[i<<1|1]);
		
	}
}
posted @ 2019-07-12 20:57  邱涵的秘密基地  阅读(126)  评论(0编辑  收藏  举报