Cod sursa(job #781820)

Utilizator radu_voroneanuVoroneanu Radu Stefan radu_voroneanu Data 25 august 2012 10:26:26
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include <stdio.h>
#include <vector>
#include <string.h>

using namespace std;

#define MAXN 200010

vector<int> G[MAXN], Gt[MAXN], Gr[MAXN];
vector<int>::iterator it;
int C[MAXN], V[MAXN], Fix[MAXN], Grad[MAXN];
bool Ok[MAXN];
int x, y, i, nod, nod2;
int N, M, Q, Component;

inline int comut(const int &x)
{
	if (x < 0)
		return (-x - 1) + N;
	else
		return x - 1;
}

inline int neg(const int &x)
{
	return (x + N) % (2*N);
}

void df1(int nod)
{
	vector<int>::iterator it;
	int nod2;
	
	Ok[nod] = true;
	for (it = G[nod].begin(); it != G[nod].end(); ++it){
		nod2 = *it;
		if (!Ok[nod2])
			df1(nod2);
	}
	
	V[++Q] = nod;
}

void df2(int nod)
{
	vector<int>::iterator it;
	int nod2;
	
	Ok[nod] = true;
	C[nod] = Component;
	for (it = Gt[nod].begin(); it != Gt[nod].end(); ++it){
		nod2 = *it;
		if (!Ok[nod2])
			df2(nod2);
	}
}

int main()
{
	freopen("2sat.in","r",stdin);
	freopen("2sat.out","w",stdout);
	
	scanf("%d %d",&N, &M);
	for (i = 1; i <= M; ++i){
		scanf("%d %d",&x,&y);
		x = comut(x);
		y = comut(y);
		G[neg(x)].push_back(y);
		G[neg(y)].push_back(x);
		Gt[y].push_back(neg(x));
		Gt[x].push_back(neg(y));
	}
	
	Q = -1;
	memset(Ok, false, sizeof(Ok));
	for (i = 0; i < 2 * N; ++i)
		if (!Ok[i])
			df1(i);
		
	memset(Ok, false, sizeof(Ok));
	for (i = 2 * N - 1; i >= 0; --i)
		if (!Ok[V[i]]){
			Component = V[i];
			df2(V[i]);
		}
		
	for (i = 0; i < N; ++i)
		if (C[i] == C[neg(i)]){
			printf("-1\n");
			return 0;
		}
	
	for (i = 0; i < 2 * N; ++i)
		for (it = G[i].begin(); it != G[i].end(); ++it){
			nod = *it;
			if (C[nod] == C[i]) continue;
			Gr[C[i]].push_back(C[nod]);
			++Grad[C[nod]];
		}
	
	Q = 0;
	for (i = 0; i < 2 * N; ++i){
		Fix[i] = -1;
		if (C[i] != i) continue;
		if (Grad[i] == 0)
			V[++Q] = i;
	}
	
	for (i = 1; i <= Q; ++i){
		//fixez componenta
		nod = V[i];
		if (Fix[nod] == -1) {
			Fix[nod] = 0;
			Fix[ C[neg(nod)] ] = 1;
		}
		
		for (it = Gr[nod].begin(); it != Gr[nod].end(); ++it){
			nod2 = *it;
			--Grad[nod2];
			if (Grad[nod2] == 0)
				V[++Q] = nod2;
		}
	}
	
	for (i = 0; i < N; ++i)
		printf("%d ", Fix[C[i]]);
	
	return 0;
}