Cod sursa(job #930651)

Utilizator taigi100Cazacu Robert taigi100 Data 27 martie 2013 19:21:25
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include<stdio.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<cassert>
using namespace std;

#define max 200005

int vars,exps;

vector<int> adj[max],adj_t[max],vtc(max),value(max,-1),scc_in_deg(max,0);

vector< vector<int> > finals;

int abs(int x)
{
	return (x<0) ? -x:+x;
}
int idx(int x)
{
	return (x<0) ? abs(x)+vars:x;
}
int non(int x)
{
	return (x>vars) ? x-vars:x+vars;
}
void DFP(int n, vector<int> &used, vector<int>& discover)
{
	vector<int>::iterator it;
	used[n]=1;
	for(it=adj[n].begin();it!=adj[n].end();it++)
		if(!used[*it])
			DFP(*it,used,discover);
	discover.push_back(n);
}
void DFM(int n, vector<int> &used, vector<int>& discover)
{
	used[n]=1;
	discover.push_back(n);
	for(vector<int>::iterator it=adj_t[n].begin(); it!=adj_t[n].end();it++)
		if(!used[*it])
			DFM(*it,used,discover);
}
void compute_finals()
{
	vector<int> used(max), discover, final;

	used.assign(used.size(),0);
	for(int i=1;i<=vars*2;++i)
	{
		if(!used[i])
			DFP(i,used,discover);
	}
	used.assign(used.size(),0);
	vector<int>::reverse_iterator it;
	vector<int>::iterator zs;
	for(it=discover.rbegin(); it!=discover.rend();it++)
		if(!used[*it])
		{
			final.clear();
			DFM(*it,used,final);
			for( zs=final.begin(); zs!=final.end();zs++)
				vtc[*zs]=finals.size();
			finals.push_back(final);
		}
}
int main()
{
	freopen("2sat.in","r",stdin);
    freopen("2sat.out","w",stdout);

	scanf("%d %d",&vars,&exps);

	for(int i=0;i<exps;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		adj[non(idx(x))].push_back(idx(y));
		adj_t[idx(y)].push_back(non(idx(x)));
		adj[non(idx(y))].push_back(idx(x));
		adj_t[idx(x)].push_back(non(idx(y)));
	}

	compute_finals();

	int fuckyou=false;

	for(int i=1;i<=vars;i++)
	{
		if(vtc[i]== vtc[i+vars])
			fuckyou=true;
	}

	if(!fuckyou)
	{
		for(int i=1;i<=vars*2;i++)
		{
			vector<int>::iterator it;
			for(it=adj[i].begin();it!=adj[i].end();it++)
				if(vtc[i]!=vtc[*it])
					scc_in_deg[vtc[*it]]++;
		}
		queue<int> pussy;
		for(int i=0;i<(int) finals.size() ; i++)
		{
			if(scc_in_deg[i]==0)
				pussy.push(i);
		}
		while(!pussy.empty())
		{
			int ix=pussy.front();
			pussy.pop();
			vector<int>::iterator it,i,j;
			for(it = finals[ix].begin();it!=finals[ix].end();it++)
			{
				int x=(*it>vars) ? *it-vars:*it;
				if(value[x]==-1)
					value[x]=(*it <= vars ) ? 0:1;
			}
			for(i=finals[ix].begin();i!=finals[ix].end();i++)
			{
				for(j=adj[*i].begin();j!=adj[*i].end();j++)
					if(vtc[*i]!=vtc[*j])
						if((-- scc_in_deg[vtc[*j]])==0)
							pussy.push(vtc[*j]);
			}
		}
		for(int i=1;i<=vars;i++)
			printf("%d ",value[i]);
	}
	else
		printf("-1");
}