2-SAT 板子。

const int N = 2e6 + 10;

int n, m;

struct edge
{
	int to, nxt;
}e[N << 1];
int head[N], tot;

void add (int u, int v)
{
	e[++tot] = (edge){v, head[u]}, head[u] = tot;
}

int dfn[N], low[N], cnt;
int col[N], colcnt;
int stk[N], top;
bool vis[N];

void Tarjan(int u)
{
	dfn[u] = low[u] = ++cnt;
	stk[++top] = u;
	vis[u] = 1;
	for (int i = head[u]; i; i = e[i].nxt)
	{
		int v = e[i].to;
		if (!dfn[v])
		{
			Tarjan(v);
			low[u] = min(low[u], low[v]);
		} 
		else if (vis[v]) low[u] = min(low[u], dfn[v]); 
	}
	if (dfn[u] == low[u])
	{
		colcnt++;
		while(stk[top] != u)
		{
			col[stk[top]] = colcnt;
			vis[stk[top]] = 0;
			top --;
		}
		col[stk[top]] = colcnt;
		vis[stk[top]] = 0;
		top --;
	}
}

int main()
{
	scanf ("%d%d", &n, &m);
	for (int i = 1; i <= m; i++)
	{
		int a, x, b, y;
		scanf ("%d%d%d%d", &a, &x, &b, &y);
		if (!x && !y) add(a, b + n), add(b, a + n);
		if (!x && y) add(a, b), add(b + n, a + n);
		if (x && !y) add(a + n, b + n), add(b, a);
		if (x && y) add(a + n, b), add(b + n, a);
	}
	for (int i = 1; i <= 2 * n; i++)
		if (!dfn[i]) Tarjan(i);
	for (int i = 1; i <= n; i++)
		if (col[i] == col[i + n])
		{
			puts("IMPOSSIBLE");
			return 0;
		}
	puts("POSSIBLE");
	for (int i = 1; i <= n; i++)
		printf ("%d ", col[i] < col[i + n]);
	return 0;
}
EOF

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。

博客信息

作者
Jayun
时间
2023-11-12 19:46:47
博客类型