Cod sursa(job #518512)

Utilizator ciprianfFarcasanu Alexandru Ciprian ciprianf Data 1 ianuarie 2011 16:15:16
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define NMAX 200010
vector <int> G[NMAX], Gt[NMAX], V[NMAX];
int T[NMAX], viz[NMAX], out[NMAX];
int other[NMAX];
/*#define G (G + 100000)
#define Gt (Gt + 100000)
#define T (T + 100000)
#define viz (viz + 100000)*/
#define FOR(i, v) for(vector<int>::iterator i = v.begin(); i != v.end(); ++i)
int st[NMAX], R[NMAX], deg[NMAX];
int n, m, k;
int nr;
int comp;
inline int abs(int x){
	if(x > 0) return x;
	return n-x;
}
void df(int x){
	viz[x] = 1;
	FOR(i, G[x])
		if(!viz[*i])
			df(*i);
	st[++k] = x;
	//out[x] = k;
}
void df2(int x){
	viz[x] = 1;
	T[x] = comp;
	FOR(i, Gt[x])
		if(!viz[*i])
			df2(*i);
}
void compact(){
	for(int i = 1; i <= 2*n; ++i)
		if(i != 0 && !viz[i])
			df(i);
	for(int i = 1; i <= n; ++i)
		viz[i] = viz[n+i] = 0;
	for(int i = k; i; --i)
		if(!viz[st[i]]){
			comp++;
			df2(st[i]);
		}
}
int check(){
	for(int i = 1; i <= n; ++i)
		if(T[i] == T[abs(-i)]) {
			printf("-1\n");
			return 1;
		}
	return 0;
}
void df3(int x){
	viz[x] = 1;
	FOR(i, V[x])
		if(!viz[*i])
			df3(*i);
	out[x] = ++nr;
}
void solve(){
	for(int x = 1; x <= 2*n; ++x)
		FOR(i, G[x])
			if(T[x] != T[*i]) {
				V[T[x]].push_back(T[*i]);
				deg[T[*i]]++;
			}
	for(int i = 1; i <= n; ++i)
		other[T[i]] = T[abs(-i)], other[T[abs(-i)]] = T[i];
	memset(viz, 0, sizeof(viz));

	st[0] = 0;
	for(int i = 1; i <= comp; ++i)
		if(deg[i] == 0) st[++st[0]] = i;
	for(int i = 1; i <= st[0]; ++i){
		int x = st[i];
		if(R[x]) continue;
		R[other[x]] = 1;
		FOR(it, V[x]){
			deg[*it]--;
			if(deg[*it] == 0) st[++st[0]] = *it;
		}
	}
	for(int i = 1; i <= n; ++i)
		printf("%d ", R[T[i]]);
}
int main(){
	freopen("2sat.in", "r", stdin);
	freopen("2sat.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++i){
		int x, y;
		scanf("%d%d", &x, &y);
		G[abs(-x)].push_back(abs(y));
		G[abs(-y)].push_back(abs(x));
		
		Gt[abs(y)].push_back(abs(-x));
		Gt[abs(x)].push_back(abs(-y));
	}
	compact();
	if(check()) return 0;
	solve();
	//for(int i = 1; i <= n; ++i)
		//printf("0 ");
	return 0;
}