Cod sursa(job #472565)

Utilizator ooctavTuchila Octavian ooctav Data 25 iulie 2010 16:53:50
Problema 2SAT Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 4.04 kb
#include<cstdio>
#include<vector>
using namespace std;

const int NMAX = 100010;

int N, M;
vector<int> Graf[2 * NMAX];
vector<int> GT[2 * NMAX];
vector<int> Comp[2 * NMAX];
int componente;
int apart[2 * NMAX];
bool val[NMAX];
bool viz[2 * NMAX];
int ord[2 * NMAX];
int ct1;
vector<int> Graf_final[2 * NMAX];
int grad[2 * NMAX];
int ord_graf_final[2 * NMAX];
int ct2;

inline int modul(int x)
{
	if(x < 0)
		return -x;
	return x;
}

inline int cv(int x)
{
	return x + N;		
}

inline int non_cv(int x)
{
	return x - N;
}

void citire()
{
	scanf("%d%d", &N, &M);
	int x, y;
	for(int i = 1 ; i <= M ; i++)
	{
		scanf("%d%d", &x, &y);
		Graf[cv(-x)].push_back(cv(y));
		Graf[cv(-y)].push_back(cv(x));
		GT[cv(y)].push_back(cv(-x));
		GT[cv(x)].push_back(cv(-y));	
	}
}

void write()
{
	/*for(int i = 1 ; i <= 2 * N ; i++)
	{
		printf("%d : ", non_cv(i));
		for(int j = 0 ; j < Graf[i].size() ; j++)
			printf("%d ", non_cv(Graf[i][j]));
		printf("\n");
	}
	printf("\n\n\n");
	for(int i = 0 ; i <= 2 * N ; i++)
	{
		printf("%d : ", non_cv(i));
		for(int j = 0 ; j < GT[i].size() ; j++)
			printf("%d ", non_cv(GT[i][j]));
		printf("\n");
	}
	printf("\n\n\n");
	for(int i = 1 ; i <= ct1 ; i++)
		printf("%d ",  non_cv(ord[i]));
	printf("\n\n\n");
	for(int i = 1 ; i <= componente ; i++)
	{
		for(int j = 0 ; j < Comp[i].size() ; j++)
			printf("%d ", non_cv(Comp[i][j]));
		printf("\n");
	}
	for(int i = 1 ; i <= componente ; i++)
	{
		for(int j = 0 ; j < Graf_final[i].size() ; j++)
			printf("%d ",Graf_final[i][j]);
		printf("\n");
	}
	printf("\n\n\n");
	for(int i = 1 ; i <= componente ; i++)
		printf("%d ", grad[i]);
	printf("\n\n\n");
	for(int i = 1 ; i <= componente ; i++)
		printf("%d ", ord_graf_final[i]);
	printf("\n\n\n");*/
}

void DFS(int x)
{
	viz[x] = 1;
	for(int i = 0 ; i < Graf[x].size() ; i++)
		if(!viz[Graf[x][i]])
			DFS(Graf[x][i]);
	ord[++ct1] = x;
}

int DFST(int x)
{
	if(!viz[x])
		return 0;
	viz[x] = 0;
	Comp[componente].push_back(x);
	apart[x] = componente;
	for(int i = 0 ; i < GT[x].size() ; i++)
		if(viz[GT[x][i]])
			DFST(GT[x][i]);
	return 1;
}

void CTC()
{
	for(int i = 0 ; i <= 2 * N ; i++)
		if(non_cv(i) && !viz[i])
			DFS(i);
	for(int i = ct1 ; i ; i--)
	{
		componente++;
		if(!DFST(ord[i]))
			componente--;
	}
			
}

bool ver()
{
	for(int i = 0 ; i < N ; i++)
		if(apart[non_cv(i)] == apart[cv(-non_cv(i))])
			return 0;
	return 1;
}

void face_graf()
{
	for(int i = 1 ; i <= componente ; i++)
	{
		bool relatie[2 * NMAX] = {0};
		relatie[i] = 1;
		for(int j = 0 ; j < Comp[i].size() ; j++)
			for(int k = 0 ; k < Graf[Comp[i][j]].size() ; k++)
				if(!relatie[apart[Graf[Comp[i][j]][k]]])
				{
					Graf_final[i].push_back(apart[Graf[Comp[i][j]][k]]);
					grad[apart[Graf[Comp[i][j]][k]]]++;
					relatie[apart[Graf[Comp[i][j]][k]]] = 1;
				}
	}
}

void sort_topologic()
{
	
	for(int i = 1 ; i <= componente ; i++)
		if(!grad[i])
			ord_graf_final[++ct2] = i;
	for(int i = 1 ; i <= ct2 ; i++)
		for(int j = 0 ; j < Graf_final[ord_graf_final[i]].size() ; j++)
		{
			grad[Graf_final[ord_graf_final[i]][j]]--;
			if(grad[Graf_final[ord_graf_final[i]][j]] == 0)
				ord_graf_final[++ct2] = Graf_final[ord_graf_final[i]][j];
		}
		
}

void atribuire_valori()
{
	int v_moment = 0;
	bool viz[NMAX];
	for(int i = 1 ; v_moment < N ; i++)
	{
		for(int k = 0 ; k < Comp[ord_graf_final[i]].size() ; k++)
			if(!viz[modul(non_cv(Comp[i][k]))])
			{
				viz[modul(non_cv(Comp[i][k]))] = 1;
				if(non_cv(Comp[i][k]) < 0)
					val[modul(non_cv(Comp[i][k]))] = 1;
			}
		v_moment += Comp[ord_graf_final[i]].size();
	}
}

void scrie(int x)
{
	if(!x)
		printf("%d\n", -1);
	else
	{
		for(int i = 1 ; i <= N ; i++)
			printf("%d ", val[i]);
		printf("\n");
	}
}

int main()
{
	freopen("2sat.in", "r", stdin);
	freopen("2sat.out", "w", stdout);
	citire();
	CTC();
	if(!ver())
	{
		scrie(0);
		return 0;
	}
	face_graf();
	sort_topologic();
	//write();
	atribuire_valori();
	scrie(1);
	return 0;
}