Cod sursa(job #1542932)

Utilizator tavy14tIlie Octavian tavy14t Data 5 decembrie 2015 20:03:06
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.9 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

template <class T>
class List {
public:
	List()
	{
		size = 0;
		first = NULL;
	}

	void Insert(T value)
	{
		Nod<T> *temp = new Nod<T>;
		temp->value = value;
		temp->next = first;
		first = temp;
		size++;
	}

	void Remove(T value)
	{
		if (first != NULL)
		{

			while (first->value == value)
			{
				if (first->next != NULL)
				{
					Nod<T>* forDelete = first;
					first = first->next;
					cout << forDelete << "\n" << first << "\n";
					delete forDelete;
					size--;
				}
				else
				{
					first = NULL;
					size = 0;
					break;
				}
			}

			Nod<T>* temp1 = first;
			if (temp1 != NULL)
				while (temp1->next != NULL)
				{
					if (temp1->next->value == value)
					{
						Nod<T>* temp2 = temp1->next;
						temp1->next = temp1->next->next;
						size--;
						delete temp2;
					}
					if (temp1->next == NULL)
						break;
					else
						temp1 = temp1->next;
				}
		}
	}

	void Clear()
	{
		if (first != NULL)
		{
			Nod<T> *temp1 = first;
			Nod<T> *temp2 = first->next;
			while (temp2)
			{
				delete temp1;
				temp1 = temp2;
				temp2 = temp2->next;
			}
			first = NULL;
			size = 0;
		}
	}

	unsigned int Size()
	{
		return size;
	}

	T operator[](int index)
	{
		if (index >= size || index < 0)
		{
			throw "Element not found!";
		}
		else
		{
			Nod<T>* temp = first;
			for (int i = 0; i < size - index - 1; i++)
				temp = temp->next;
			return temp->value;
		}
	}

private:
	template <class T>
	struct Nod {
		T value;
		Nod* next;
	};
	Nod<T>* first;
	int size;
};

ifstream f("2sat.in");
ofstream g("2sat.out");
int n, m, nrComponenteConexe; // n = nr variabile, m = nr clauze
List<int> digraf[200001];
vector<int> vizitat, stiva, culoare;

void citire()
{
	f >> n >> m;
	
	for (int i = 1; i <= m; i++)
	{
		int x1, x2;
		f >> x1 >> x2;

		x1 = (x1 <= 0 ? -x1 : x1 + n);
		x2 = (x2 <= 0 ? -x2 : x2 + n);

		if (x1<= n)
		{
			if (x2 <= n) // !x1 V !x2 = x1 -> !x2 = x2 -> !x1
			{	
				digraf[x2].Insert(n + x1);
				digraf[x1].Insert(n + x2);
				//digrafTranspus[n + x1].Insert(x2);
				//digrafTranspus[n + x2].Insert(x1);
			}
			else  //  !x1 V x2 = !x2 -> !x1 = x1 -> x2
			{
				digraf[x1].Insert(x2 - n);
				digraf[x2].Insert(x1 + n);
				//digrafTranspus[x2 - n].Insert(x1);
				//digrafTranspus[x1 + n].Insert(x2);
			}
		}
		else
		{
			if (x2 <= n) // x1 V !x2 = !x1 -> !x2 = x2 -> x1
			{
				digraf[x2].Insert(x1 - n);
				digraf[x1].Insert(x2 + n);
				//digrafTranspus[x1 - n].Insert(x2);
				//digrafTranspus[x2 + n].Insert(x1);
			}
			else // x1 V x2 = !x1 -> x2 = !x2 -> x1 
			{
				digraf[x2].Insert(x1 - n);
				digraf[x1].Insert(x2 - n);
				//digrafTranspus[x1 - n].Insert(x2);
				//digrafTranspus[x2 - n].Insert(x1);
			}
		}
	}
}

void afisare()
{
	for (int i = 1; i <= 2 * n; i++)
	{
		cout << i << " : ";
		for (int j = 0; j < digraf[i].Size(); j++)
			cout << digraf[i][j] << " ";
		cout << endl;
	}
	cout << "-------------------------------" << endl;
	/*for (int i = 1; i <= 2 * n; i++)
	{
		cout << i << " : ";
		for (int j = 0; j < digrafTranspus[i].Size(); j++)
			cout << digrafTranspus[i][j] << " ";
		cout << endl;
	}*/
}

void dfs(int nod)
{
	vizitat[nod] = 1;
	for (int j = 0; j < digraf[nod].Size(); j++)
		if (vizitat[digraf[nod][j]] == 0)
			dfs(digraf[nod][j]);
		
	stiva.push_back(nod);
}

void dfs2(int nod, int nrCuloare)
{
	culoare[nod] = nrCuloare;
	for (int j = 0; j < digraf[nod].Size(); j++)
		if (culoare[digraf[nod][j]] == 0)
			dfs2(digraf[nod][j], nrCuloare);
}

void kosaraju()
{
	for (int i = 1; i <= 2 * n + 1; i++)
	{
		vizitat.push_back(0);
		culoare.push_back(0);
	}
	for (int i = 1; i <= 2 * n; i++)
		if (vizitat[i] == 0)
			dfs(i);

	int nrCuloare = 1;
	for (int i = 0; i < stiva.size(); i++)
		if (culoare[stiva[i]] == 0)
		{
			dfs2(stiva[i], nrCuloare);
			nrCuloare++;
		}
	nrComponenteConexe = nrCuloare - 1;
}

void literaliContrari()
{
	for (int lit1 = 1; lit1 < 2 * n; lit1++)
		for (int lit2 = lit1+1; lit2 <= 2 * n; lit2++)
			if (culoare[lit1] == culoare[lit2] && lit1 != lit2)
			{
				if (lit1 <= n && lit1 + n == lit2)
				{
					g << -1;
					return;
				}
				else if (lit2 <= n && lit2 + n == lit1)
				{
					g << -1;
					return;
				}
			}
}

void parcurgereTopologica()
{
	bool *valoare = new bool[n+1];
	for (int i = nrComponenteConexe; i >= 1; i--)
	{
		for (int j = 1; j <= 2 * n; j++)
			if (culoare[j] == i)
			{
				if (i > nrComponenteConexe/2)
				{
					if (j <= n)
						valoare[j] = 1;
					else 
						valoare[j-n] = 0;
				}
			}
	}
	for (int i = 1; i <= n; i++)
		g << !valoare[i] << " ";
}

int main()
{
	citire();
	//afisare();
	kosaraju();
	literaliContrari();
	parcurgereTopologica();

	f.close();
	g.close();
}