Cod sursa(job #663869)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 19 ianuarie 2012 08:20:32
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <bitset>
#include <algorithm>

#define MAXN	100001

using namespace std;

typedef unsigned int uint32;
typedef vector<vector<int> > Graph;
typedef vector<vector<int> > Scc;

bitset<2*MAXN> visitedNodes_1;
bitset<2*MAXN> visitedNodes_2;

uint32 formula[2*MAXN+1];
uint32 whatComponent[2*MAXN+1];

uint32 numComp = 0;
stack<uint32> stNodes;

inline uint32 non(const uint32 x, const uint32 n)
{
	return (x>=n) ? (x - ((x-n)*2 + 1)) : (x + ((n-x)*2 - 1));
}

inline int original(const uint32 x, const uint32 n)
{
	return (x>=n) ? (x-n+1) : (x-n);
}

void Kosaraju_1(const Graph& graph, const uint32 node)
{
	for (uint32 i=0; i<graph[node].size(); ++i)
	{
		if (false == visitedNodes_1[graph[node][i]])
		{
			visitedNodes_1[graph[node][i]] = true;
			Kosaraju_1(graph, graph[node][i]);
		}
	}

	stNodes.push(node);
}


void Kosaraju_2_DFS(const Graph& graph, vector<int>& scc, uint32 node)
{
	scc.push_back(node);
	whatComponent[node] = numComp;
	visitedNodes_2[node] = true;

	for (uint32 i=0; i<graph[node].size(); ++i)
	{
		if (false == visitedNodes_2[graph[node][i]])
		{	
			Kosaraju_2_DFS(graph, scc, graph[node][i]);
		}
	}
}

int main()
{
	uint32 variables, statements;
	Graph graph, graphT;
	Scc sccs;
	fstream fin("2sat.in", fstream::in);
	fstream fout("2sat.out", fstream::out);
	
	fin >> variables >> statements;
	//cout << variables << " " << statements << endl;
	
	//n = variables;
	//m = statements;

	graph.resize(2*variables);
	graphT.resize(2*variables);
	sccs.resize(2*variables);
	
	for (uint32 i=0; i<statements; ++i)
	{
		int x, y;
		fin >> x >> y;
		
		if (x<0)
		{
			x += variables;
		}
		else
		{
			x += (variables-1);
		}
		if (y<0)
		{
			y += variables;
		}
		else
		{
			y += (variables-1);
		}

		graph[non(x, variables)].push_back(y);
		graph[non(y, variables)].push_back(x);
		
		graphT[y].push_back(non(x, variables));
		graphT[x].push_back(non(y, variables));
	}
	
	for (uint32 i=0; i<2*variables; ++i)
	{
		if (false == visitedNodes_1[i])
		{
			visitedNodes_1[i] = true;
			Kosaraju_1(graph, i);
		}
	}
	
	while (!stNodes.empty())
	{
		const uint32 node = stNodes.top();
		stNodes.pop();
		
		//cout << node << endl;

		if (false == visitedNodes_2[node])
		{
			//Kosaraju_2_BFS(graphT, sccs[numComp], node);
			Kosaraju_2_DFS(graphT, sccs[numComp], node);
			numComp++;
		}
	}

	for (uint32 i=0; i<variables; ++i)
	{
		if (whatComponent[i] == whatComponent[non(i, variables)])
		{
			fout << -1;
			return 0;
		}
	}

	for (uint32 i=0; i<numComp; ++i)
	{
		for (uint32 j=0; j<sccs[i].size(); ++j)
		{
			if (0 == formula[sccs[i][j]])
			{
				formula[sccs[i][j]] = 1;
				formula[non(sccs[i][j], variables)] = 2;
			}
		}
	}
	
	for (uint32 i=variables; i<2*variables; ++i)
	{
		fout << formula[i]-1 << " ";
	}
	fout << "\n";
	
	fin.close();
	fout.close();
	return 0;
}