2-SAT求调
查看原帖
2-SAT求调
214696
Dry_ice楼主2022/7/18 23:48

30pts WA

#include <stdio.h>
#include <string.h>
#define AE(x, y) Add_Edge((x), (y))
#define mn(x, y) ((x) < (y) ? (x) : (y))
template<typename Tp>
inline void Read(Tp &x) {
	x = 0; bool w = 0; char c = getchar();
	for (; c < '0' || c > '9'; c = getchar()) if (c == '-') w ^= 1;
	for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
	if (w) x = -x;
}
const int N = (int)2e6 + 5, M = (int)1e6 + 5;
int hd[N], eL;
struct Edge {int to, nxt;} e[M << 1];
inline void Add_Edge(int fr, int to) {
	e[++eL] = (Edge){to, hd[fr]};
	hd[fr] = eL;
}
int n, m, ti, dfn[N], lo[N], scc[N];
int st[N], tp, Res; bool vis[N];
inline void tarjan(int u) {
	dfn[u] = lo[u] = ++ti; st[++tp] = u; vis[u] = true;
	for (int i = hd[u]; i; i = e[i].nxt) {
		int v = e[i].to;
		if (!dfn[v]) {
			tarjan(v);
			lo[u] = mn(lo[v], lo[u]);
		}
		else if (vis[v]) lo[u] = mn(dfn[v], lo[u]);
	}
	if (dfn[u] == lo[u]) {
		++Res;
		while (tp) {
			scc[st[tp]] = Res, vis[st[tp]] = false;
			if (st[tp--] == u) break;
		}
	}
}
int main(void) {
	eL = 0; Read(n), Read(m);
	for (int i = 1, a, b, c, d, e, f; i <= m; ++i) {
		Read(a), Read(b), Read(c), Read(d);
        e = b ^ 1, f = d ^ 1;
		AE(a + e * n, c + d * n); AE(c + f * n, a + b * n);
//		printf("%d %d %d %d\n", a + b * n, c + d * n, c + (d ^ 1) * n, a + (b ^ 1) * n);
	}
	ti = tp = Res = 0; memset(scc, 0, sizeof scc); memset(vis, false, sizeof vis);
	for (int i = 1; i <= 1 << n; ++i) if (!dfn[i]) tarjan(i);
	for (int i = 1; i <= n; ++i)
		if (scc[i] == scc[i + n]) {
			puts("IMPOSSIBLE");
			return 0;
		}
	puts("POSSIBLE");
	for (int i = 1; i <= n; ++i)
		printf("%d ", scc[i] > scc[i + n]);
	return 0;
}
2022/7/18 23:48
加载中...