Cod sursa(job #2651795)

Utilizator MarcGrecMarc Grec MarcGrec Data 23 septembrie 2020 16:33:39
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 kb
#define MAX_N 100000

#include <fstream> 
#include <vector>
#include <utility>
#include <list>
using namespace std;

ifstream fin("2sat.in");
ofstream fout("2sat.out");

int n, m;

struct NodeInfo
{	
	NodeInfo(int _value = -1) : value(_value), outF(), outT()
	{
	}
	
	int value;
	
	vector<pair<int, int>> outF;
	
	vector<pair<int, int>> outT;
};

list<int> GC;

NodeInfo G[MAX_N + 1];

void Read();

bool Dfs(int node);

int main()
{
	Read();
	
	bool solFound = true;
	
	for (int i = 1; i <= n; ++i)
	{	
		if (G[i].value == -1)
		{
			G[i].value = 0;
			
			GC.push_back(i);
			
			if (!Dfs(i))
			{
				for (int node : GC)
				{
					G[node].value = -1;
				}
				
				G[i].value = 1;
				
				GC.push_back(i);
				
				if (!Dfs(i))
				{
					solFound = false;
					break;	
				}
			}
			
			GC.clear();
		}
	}
	
	if (solFound)
	{
		for (int i = 1; i <= n; ++i)
		{
			fout << G[i].value << ' ';
		}
	}
	else
	{
		fout << "-1";
	}
	
	fin.close();
	fout.close();
	return 0;
}

void AddEdge(int x, int y)
{
	if ((x > 0) && (y > 0))
	{
		G[x].outF.emplace_back(y, 1);
		return;
	}
	
	if ((x > 0) && (y < 0))
	{
		G[x].outF.emplace_back(-y, 0);
		return;
	}
	
	if ((x < 0) && (y > 0))
	{
		G[-x].outT.emplace_back(y, 1);
		return;
	}
	
	if ((x < 0) && (y < 0))
	{
		G[-x].outT.emplace_back(-y, 0);
		return;
	}
}

void Read()
{
	fin >> n >> m;
	
	for (int i = 0; i < m; ++i)
	{
		int x, y;
		
		fin >> x >> y;
		
		AddEdge(x, y);
		
		AddEdge(y, x);
	}
}

bool Dfs(int node)
{
	const bool nodeVal = G[node].value > 0;
	
	vector<pair<int, int>>& cont = (!nodeVal) ? G[node].outF : G[node].outT;
	
	for (const auto& adjNode : cont)
	{
		if (G[adjNode.first].value == -1)
		{
			G[adjNode.first].value = adjNode.second;
			
			GC.push_back(adjNode.first);
			
			if (!Dfs(adjNode.first))
			{
				return false;
			}
		}
		else
		{
			if (G[adjNode.first].value != adjNode.second)
			{
				return false;
			}
		}
	}
	
	return true;
}