Cod sursa(job #2669072)

Utilizator akumariaPatrascanu Andra-Maria akumaria Data 5 noiembrie 2020 23:52:29
Problema 2SAT Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.59 kb
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

#define MAXN 100005


int n;
vector<int> used(MAXN * 2, 0);
vector<int> arcs[MAXN * 2], back_arcs[MAXN * 2];
vector<int> discoveryOrder, stronglyConnectedOrder, variableInComponent(MAXN * 2), sccDegs, result;
vector<vector<int>> allComponents;


int abs(int a) {
	return a <=0 ? -a : a;
}


int getIndex(int a) {
	return a < 0 ? -a + n : a;
}


int neg(int a) {
	return a > n ? a - n : a + n;
}


void stronglyConnected(int current_node) {
	used[current_node] = true;
	for(int i=0; i<arcs[current_node].size(); ++i)
		if (! used[arcs[current_node][i]])
			stronglyConnected(arcs[current_node][i]);
	discoveryOrder.push_back(current_node);
}



void stronglyConnectedBackArcs(int current_node) {
	used[current_node] = true;
	stronglyConnectedOrder.push_back(current_node);
	for(int i=0; i<back_arcs[current_node].size(); ++i)
		if (! used[back_arcs[current_node][i]])
			stronglyConnectedBackArcs(back_arcs[current_node][i]);
}



void computeComponents() {
	used.assign(MAXN, 0);
	for(int i=1; i<= 2 * n; ++i)
		if (! used[i])
			stronglyConnected(i);

	used.assign(MAXN, 0);
	for(int i=discoveryOrder.size() -1; i>=0; --i)
		if (!used[discoveryOrder[i]]) {
			stronglyConnectedOrder.clear();
			stronglyConnectedBackArcs(discoveryOrder[i]);

			for(int j=0; j<stronglyConnectedOrder.size(); ++j)
				variableInComponent[stronglyConnectedOrder[j]] = allComponents.size();
			allComponents.push_back(stronglyConnectedOrder);
		}
}


bool isImpossible() {
	for(int i=1; i<=n; ++i)
		if (variableInComponent[i] == variableInComponent[i+n])
			return true;
	return false;
}


void calculateComponentsDegs() {
	sccDegs.assign(allComponents.size(), 0);
	for(int i=1; i<=n*2; ++i) {
		for(int j=0; j<arcs[i].size(); ++j)
			if (variableInComponent[i] != variableInComponent[arcs[i][j]])
				++sccDegs[variableInComponent[arcs[i][j]]];
	}
}

void componentsBFS() {
	queue <int> q;
	int current_component, current_variable;

	for(int i=0; i<allComponents.size(); ++i)
		if (sccDegs[i] == 0)
			q.push(i);

	while (! q.empty()) {
		current_component = q.front();
		q.pop();
		for(int i=0; i<allComponents[current_component].size(); ++i) {
			current_variable = allComponents[current_component][i];
			current_variable = current_variable <= n? current_variable : current_variable - n;
			if (result[current_variable] == -1)
				result[current_variable] = allComponents[current_component][i] <=n? 0 : 1;

			current_variable = allComponents[current_component][i];
			for(int j=0; j<arcs[current_variable].size(); ++j) {
				if (variableInComponent[current_variable] != variableInComponent[arcs[current_variable][j]]) {
					--sccDegs[variableInComponent[arcs[current_variable][j]]];
					if (sccDegs[variableInComponent[arcs[current_variable][j]]] == 0)
						q.push(variableInComponent[arcs[current_variable][j]]);
				}
			}
		}

	}
}


int main() {
	freopen("2sat.in", "r", stdin);
	freopen("2sat.out", "w", stdout);

	int m, a, b;
	scanf("%d%d", &n, &m);
	for(int i=1; i<=m; ++i) {
		scanf("%d%d", &a, &b);

		back_arcs[getIndex(a)].push_back(neg(getIndex(b)));
		back_arcs[getIndex(b)].push_back(neg(getIndex(a)));

		arcs[neg(getIndex(a))].push_back(getIndex(b));
		arcs[neg(getIndex(b))].push_back(getIndex(a));
	}

	computeComponents();

	if (isImpossible()) {
		printf("-1\n");
		return 0;
	}

	calculateComponentsDegs();
	result.assign(n+1, -1);
	componentsBFS();

	for(int i=1; i<=n; ++i)
		printf("%d ", result[i]);
	printf("\n");

	return 0;
}