2 - sat 模板

2 - sat 模板

P4782 【模板】2-SAT 问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 2e6 + 10;
int n, m;
vector<vector<int> > G(N);
stack<int> stk;
int tin[N], tim;
int scc_cnt, id[N], low[N];
bool in_stk[N];
void add(int u, int v)
{
	G[u].emplace_back(v);
}

void tarjan(int u)
{
	tin[u] = low[u] = ++tim;
	stk.push(u);
	in_stk[u] = true;
	for (int v : G[u])
	{
		if (!tin[v])
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (in_stk[v])
			low[u] = min(low[u], tin[v]);
	}
	if (tin[u] == low[u])
	{
		++scc_cnt;
		int y;
		do
		{
			y = stk.top();
			stk.pop();
			in_stk[y] = false;
			id[y] = scc_cnt;
		}while(y != u);
	}
}
int main()
{
	scanf("%d%d", &n, &m);
	while(m--)
	{
		int i, a, j, b;
		scanf("%d%d%d%d", &i, &a, &j, &b);
		i--, j--;
		add(2 * i + !a, 2 * j + b);
		add(2 * j + !b, 2 * i + a);
	}

	for (int i = 0; i < 2 * n; i++)
		if (!tin[i])
			tarjan(i);

	for (int i = 0; i < n; i++)
	{
		if (id[i*2] == id[i*2+1])
		{
			puts("IMPOSSIBLE");
			return 0;
		}
	}
	puts("POSSIBLE");
	for (int i = 0; i < n; i++)
	{
		if (id[i*2] < id[i*2+1])
			putchar('0');
		else
			putchar('1');
		putchar(' ');
	}
    return 0;
}
posted @ 2022-06-10 15:40  hzy0227  阅读(19)  评论(0编辑  收藏  举报