Cod sursa(job #452793)

Utilizator FlorianFlorian Marcu Florian Data 10 mai 2010 19:59:01
Problema 2SAT Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
using namespace std;
#include<fstream>
#include<vector>
#include<queue>
#define pb push_back
const int MAX_N = 200007;
vector<int> G[MAX_N], Gt[MAX_N], L[MAX_N];
int C[MAX_N], P, N, M, viz[MAX_N], d[MAX_N], sol[MAX_N];
vector<int> A[MAX_N], pl;
queue<int>Q;
inline int non(int x) { return (x > N)?x-N:x+N; }
void DFP(int x)
{
	if(viz[x]) return;
	viz[x] = 1;
	int i;
	for(i = 0; i < G[x].size(); ++i)
		DFP(G[x][i]);
	pl.pb(x);
}
void DFM(int x)
{
	if(viz[x]) return;
	int i;
	C[x] = P; L[P].pb(x); viz[x] = 1;
	for(i = 0; i < Gt[x].size(); ++i)
		DFM(Gt[x][i]);
}
int main()
{
	ifstream in("2sat.in"); ofstream out("2sat.out");
	in>>N>>M;
	int x, y, i, j;
	for(i = 1; i <= M; ++i)
	{
		in>>x>>y;
		if(x < 0 ) x = -x + N;
		if(y < 0 ) y = -y + N;
		G[non(x)].pb(y); Gt[y].pb(non(x));
		G[non(y)].pb(x); Gt[x].pb(non(y));
	}
	for(i=1; i <= 2*N; ++i)
		if(!viz[i])
			DFP(i);
	memset(viz, 0, sizeof(viz));
	for(i = pl.size() - 1; i >= 0; --i)
		if( !viz[ pl[i] ] )
		{
			P++;
			DFM(pl[i]);
		}
	int ok = 1;
	for(i = 1; i <= N; ++i)
		if( C[i] == C[ non(i) ] ) ok = 0;
	if(ok == 0) {  out<<"-1\n"; return 0; }
	
	for(x = 1; x <= 2*N; ++x)
		for(j = 0; j < (int)G[x].size(); ++j)
		{
			y = G[x][j];
			if( C[x] != C[y] )
			{
				A[x].pb(y);
				d[y]++;
			}
		}
	for(i = 1; i <= P; ++i)
		if(d[i] == 0) Q.push(i);
	for(;!Q.empty();Q.pop())
	{
		x = Q.front();
		for(i = 0; i < L[x].size(); ++i)
		{
			y = L[x][i];
			if(sol[y]) continue;
			sol[y] = 1;
			sol[non(y)] = 2;
		}
		for(i = 0; i < A[x].size(); ++i)
		{
			y = A[x][i];
			d[y]--;
			if(d[y] == 0) Q.push(y);
		}
	}
	for(i = 1; i <= N; ++i)
		out<<sol[i] - 1<<" ";
	return 0;
}