2-SAT

2-SAT

还没学,改题时简单学了下,先咕着。

先暂时挂个板子。

#include <bits/stdc++.h>
#define il inline

using namespace std;

il int read() {
	int x = 0; char ch = getchar(); bool t = 0;
	while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
	return t ? -x : x;
}
const int N = 2e6 + 10;
int n, m;
il int V(int x, int a) {
	return a ? x : x + n;
}
vector<int> G[N];
int dfn[N], low[N], tot, scc[N], inst[N], st[N], head, cnt;
il void tarjan(int x) {
	dfn[x] = low[x] = ++tot;
	st[++head] = x; inst[x] = 1;
	for (int y : G[x]) {
		if (!dfn[y]) {
			tarjan(y);
			low[x] = min(low[x], low[y]);
		} else if (inst[y]) {
			low[x] = min(low[x], dfn[y]);
		}
	}
	if (dfn[x] == low[x]) {
		cnt++;
		while (true) {
			int y = st[head--];
			inst[y] = 0;
			scc[y] = cnt;
			if (x == y) break;
		} 
	}
}
int main() {
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), a = read(), y = read(), b = read();
		G[V(y, b ^ 1)].push_back(V(x, a));
		G[V(x, a ^ 1)].push_back(V(y, b));
	}
	for (int i = 1; i <= n * 2; i++) {
		if (!dfn[i]) tarjan(i);
	}
	for (int i = 1; i <= n; i++) {
		if (scc[i] == scc[i + n]) {
			printf("IMPOSSIBLE\n");
			return 0;
		}
	}
	printf("POSSIBLE\n");
	for (int i = 1; i <= n; i++) {
		if (scc[i + n] < scc[i]) {
			printf("0 ");
		} else {
			printf("1 ");
		}
	}
	
	return 0;
}
posted @ 2025-07-22 17:32  Zctf1088  阅读(11)  评论(0)    收藏  举报