Cod sursa(job #383925)

Utilizator savimSerban Andrei Stan savim Data 18 ianuarie 2010 19:28:02
Problema 2SAT Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <stdio.h>
#include <vector>
#include <string.h>

using namespace std;

#define MAX_N 200010

int n, m, p, q, k;
int sol[MAX_N], stiv[MAX_N], use[MAX_N], comp[MAX_N];
vector <int> G[MAX_N], A[MAX_N], ctc[MAX_N];

inline int negare(int x) {
	if (x > n) return x - n;
	else return x + n;
}

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

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

		if (p < 0) p = -p + n;
		if (q < 0) q = -q + n;

		G[negare(p)].push_back(q);
		G[negare(q)].push_back(p);

		A[q].push_back(negare(p));
		A[p].push_back(negare(q));
	}
}

void dfs(int nod) {
	use[nod] = 1;

	int len = G[nod].size();
	for (int i = 0; i < len; i++)
		if (!use[G[nod][i]])
			dfs(G[nod][i]);

	stiv[++stiv[0]] = nod;
}

void get_comp(int nod) {
	use[nod] = 1;

    ctc[k].push_back(nod);
	comp[nod] = k;
	if (nod > n && comp[nod - n] == k) sol[0] = 0;
	if (nod <= n && comp[nod + n] == k) sol[0] = 0;

	int len = A[nod].size();
	for (int j = 0; j < len; j++)
		if (!use[A[nod][j]])
			get_comp(A[nod][j]);
}

void solve() {
	for (int i = 1; i <= 2 * n; i++)
		if (!use[i])
        	dfs(i);

	sol[0] = 1;
	memset(use, 0, sizeof(use));

	for (int i = 2 * n; i >= 1; i--)
		if (!use[stiv[i]]) {
			k++;
			get_comp(stiv[i]); 
		}

	if (!sol[0]) printf("-1\n");
	else {
    	for (int i = 2 * n; i >= 1; i--) 
			if (!sol[stiv[i]]) {
				int nod = stiv[i];
				int len = ctc[comp[nod]].size();
				for (int j = 0; j < len; j++)
					sol[ctc[comp[nod]][j]] = 0;

				nod = nod - n;
				if (nod <= 0) nod += 2 * n;
				len = ctc[comp[nod]].size();
				for (int j = 0; j < len; j++)
					sol[ctc[comp[nod]][j]] = 1;
			}

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

int main() {

	cit();
	solve();

	return 0;
}