Cod sursa(job #661760)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 15 ianuarie 2012 06:12:03
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 5.37 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <bitset>
#include <algorithm>

#define MAXN	100001

using namespace std;

struct Node
{
	Node() : index(-1), lowlink(0), bIsOnStack(false)
	{}

	int index, lowlink;
	bool bIsOnStack;
};

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

uint32 formula[2*MAXN+1];
uint32 whatComponent[2*MAXN+1];
bitset<2*MAXN+1> nodeHasIncomingEdges;
bitset<2*MAXN+1> compHasIncomingEdges;

namespace TopologicalSort
{
	uint32 *orderedComponents;
	bitset<2*MAXN> visitedComponents;

	uint32 uCurrentNode;
	
	void SortComponentsTopologically(const Graph& graph, const Scc& sccs, const uint32 node)
	{	
		for (uint32 i=0; i<sccs[node].size(); ++i)
		{
			for (uint32 j=0; j<graph[sccs[node][i]].size(); ++j)
			{
				if (false == visitedComponents[whatComponent[graph[sccs[node][i]][j]]])
				{
					visitedComponents[whatComponent[graph[sccs[node][i]][j]]] = true;
					SortComponentsTopologically(graph, sccs, whatComponent[graph[sccs[node][i]][j]]);
				}
			}
		}
		
		orderedComponents[uCurrentNode++] = node;
	}
	
	inline void SortComponentsTopoligically(const Graph& graph, const Scc& sccs, uint32 uNumComp)
	{
		uCurrentNode = 0;
		orderedComponents = new uint32[uNumComp+1];
		for (uint32 i=0; i<uNumComp; ++i)
		{
			if (false == visitedComponents[i] && false == compHasIncomingEdges[i])
			{
				//cout << "Comp = " << i << endl;
				visitedComponents[i] = true;
				SortComponentsTopologically(graph, sccs, i);
			}
		}
	}
}

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 StronglyConnectedComponent
(
	const Graph& graph,
	Node *nodes,
	stack<int>& S,
	const int node,
	int& index,
	Scc& sccs,
	int& numComp
)
{
	nodes[node].index = index;
	nodes[node].lowlink = index;
	index++;
	S.push(node);
	nodes[node].bIsOnStack = true;
	
	for (int i=0; i<graph[node].size(); ++i)
	{
		if (-1 == nodes[graph[node][i]].index)
		{
			StronglyConnectedComponent(graph, nodes, S, graph[node][i], index, sccs, numComp);
			nodes[node].lowlink = min(nodes[node].lowlink, nodes[graph[node][i]].lowlink);
		}
		else if (nodes[graph[node][i]].bIsOnStack)
		{
			nodes[node].lowlink = min(nodes[node].lowlink, nodes[graph[node][i]].index);
		}
	}
	
	if (nodes[node].lowlink == nodes[node].index)
	{
		int curNode;
		do
		{
			curNode = S.top();
			sccs[numComp].push_back(curNode);
			nodes[curNode].bIsOnStack = false;
			
			whatComponent[curNode] = numComp;
			if (nodeHasIncomingEdges[curNode] == true)
				compHasIncomingEdges[numComp] = true;
			
			S.pop();
		} while(!S.empty() && curNode!=node);
		numComp++;
	}
}

int StronglyConnectedComponents(const Graph& graph, Scc& sccs)
{
	int index = 0, numComp = 0;
	Node *nodes;
	stack<int> S;
	
	nodes = new Node[graph.size()+1];
	sccs.resize(graph.size());
	
	for (int i=0; i<graph.size(); ++i)
	{
		if (-1 == nodes[i].index)
		{
			StronglyConnectedComponent(graph, nodes, S, i, index, sccs, numComp);
		}
	}
	
	if (!S.empty())
	{
		int curNode;
		do
		{
			curNode = S.top();
			sccs[numComp].push_back(curNode);
			
			whatComponent[curNode] = numComp;
			if (nodeHasIncomingEdges[curNode] == true)
				compHasIncomingEdges[numComp] = true;
			
			S.pop();
			numComp++;
		} while(!S.empty());
	}
	
	delete[] nodes;
	
	return numComp;
}

int main()
{
	uint32 numComp, variables, statements;
	Graph graph;
	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);
	
	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);
		
		nodeHasIncomingEdges[x] = true;
		nodeHasIncomingEdges[y] = true;
	}
	
	/*for (int i=0; i<n; ++i)
	{
		cout << i+1 << ": ";
		for (int j=0; j<graph[i].size(); ++j)
		{
			cout << graph[i][j]+1 << " ";
		}
		cout << endl;
	}
	
	cout << endl;*/
	
	numComp = StronglyConnectedComponents(graph, sccs);

	for (uint32 i=0; i<variables; ++i)
	{
		if (whatComponent[i] == whatComponent[non(i, variables)])
		{
			fout << -1;
			return 0;
		}
	}
	
	/*TopologicalSort::SortComponentsTopoligically(graph, sccs, numComp);
	
	//fout << numComp << "\n";
	for (int i=numComp-1; i>=0; --i)
	{
		for (uint32 j=0; j<sccs[TopologicalSort::orderedComponents[i]].size(); ++j)
		{
			if (0 == formula[sccs[TopologicalSort::orderedComponents[i]][j]])
			{
				formula[sccs[TopologicalSort::orderedComponents[i]][j]] = 1;
				formula[non(sccs[TopologicalSort::orderedComponents[i]][j], variables)] = 2;
			}
			//fout << original(sccs[TopologicalSort::orderedComponents[i]][j], variables) << " ";
		}
		//fout << "\n";
	}
	
	for (uint32 i=variables; i<2*variables; ++i)
	{
		fout << formula[i]-1 << " ";
	}
	fout << "\n";*/
	
	fin.close();
	fout.close();
	return 0;
}