Cod sursa(job #2510580)

Utilizator PetrescuAlexandru Petrescu Petrescu Data 16 decembrie 2019 21:53:43
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <set>
#include <utility>
#define MAX 100000
#define INF 2e9

using namespace std;

vector<int> graf[2 * MAX + 5];
set<int> Q;
stack<int> stiva;

bool onStack[2 * MAX + 5];
bool semafor = true;
int SAT2[2 * MAX + 5];
int up[2 * MAX + 5], viz[2 * MAX + 5], vizCount;

int max(int a, int b)
{
    if(a > b)return a;

    return b;
}

int opus(int x)
{
    if(x > MAX)x -= MAX;
    else x += MAX;

    return x;
}

void clearStack(int nod)
{
	Q.clear();

	int topNod = 0;
	while (topNod != nod)
	{
	    topNod = stiva.top();
		onStack[topNod] = 0;

		if(Q.find(opus(topNod)) != Q.end())
            semafor = false;

        Q.insert(topNod);

        if(SAT2[topNod] == 0)
        {
            SAT2[topNod] = 1;
            SAT2[opus(topNod)] = -1;
        }

		stiva.pop();
	}
}

int min(int a, int b)
{
	if (a < b)return a;

	return b;
}

void DFS(int nod)
{
	vizCount++;
	viz[nod] = vizCount;
	up[nod] = vizCount;

	stiva.push(nod);
	onStack[nod] = 1;

	for (auto i : graf[nod])
	{
		if (!viz[i])
		{
			DFS(i);

			up[nod] = min(up[nod], up[i]);
		}
		else if (onStack[i])
			up[nod] = min(up[nod], viz[i]);
	}

	if (up[nod] == viz[nod])
    {
		clearStack(nod);
    }
}

int getIndex(int x)
{
	if (x < 0)return -x + MAX;

	return x;
}

int getReversedIndex(int x)
{
	if (x < 0)return -x;

	return x + MAX;
}

int main()
{
	int n, m, a, b;

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

	fin >> n >> m;

	for (int i = 1; i <= m; i++)
	{
		fin >> a >> b;

		graf[getReversedIndex(a)].push_back(getIndex(b));
		graf[getReversedIndex(b)].push_back(getIndex(a));
	}

	for(int i = 1; i <= n; i++)
	{
	    if(graf[i].size())
        {
            cout << i << " ";
            for(auto j : graf[i])cout << j << " ";

            cout << '\n';
        }
	}

	for (int i = 1; i <= n; i++)
		if (!viz[i])
			DFS(i);

    for (int i = 1; i <= n; i++)
		if (!viz[i + MAX])
			DFS(i + MAX);

    if(semafor)
        for (int i = 1; i <= n; i++)fout << max(0, SAT2[i]) << " ";
    else fout << -1;

	fin.close();
	fout.close();

	return 0;
}