Cod sursa(job #2722992)

Utilizator MateGMGozner Mate MateGM Data 13 martie 2021 14:24:45
Problema 2SAT Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <iostream>
#include <vector>
#include <stack>
#include <fstream>
#include <algorithm>
#include <cstdio>

using namespace std;

ifstream be("2sat.in");
ofstream ki("2sat.out");

void beolvas(vector<vector<int>>& graf, int n, int m);
bool twosat(vector<vector<int>>& graf, int n, vector<int>& igazsag_ertek);
void dfs_scc(int n, vector<vector<int>>& graf, vector<int>& belep, vector<bool>& vermen, vector<int>& low, stack<int>& verem, vector<vector<int>>& komponensek, int& komponens, int& ido, int v);

int main() {
	int n, m;
	be >> n >> m;
	vector<vector<int>> graf(2 * n + 1);
	beolvas(graf, n, m);
	
	vector<int> igazsag_ertek;
	if (!twosat(graf, n, igazsag_ertek))
		//ki << "Nincs megoldas" << endl;
		ki << -1 << endl;
	else {
		for (int i = 1; i <= n; i++)
			ki << igazsag_ertek[i] << endl;
	}


}

void beolvas(vector<vector<int>>& graf, int n, int m) {
	for (int i = 0; i < m; i++) {
		int x, y;
		be >> x >> y;
		graf[-x + n].push_back(y + n);
		graf[-y + n].push_back(x + n);
	}
}

bool twosat(vector<vector<int>>& graf, int n, vector<int>& igazsag_ertek) {
	vector<int> belep(2 * n + 1, -1);
	vector<bool> vermen(2 * n + 1, false);
	vector<int> low(2 * n + 1, -1);
	stack<int> verem;
	vector<vector<int>> komponensek;
	igazsag_ertek.resize(n + 1, -1);

	int ido = 0;
	int komponens = 0;

	for (int i = 0; i <= 2 * n; i++)
		if (belep[i] == -1 && belep[i] != n) dfs_scc(n, graf, belep, vermen, low, verem, komponensek, komponens, ido, i);

	for (int i = 0; i < komponensek.size(); i++) {
		int akt_igaz = -1;
		for (int j = 0; j < komponensek[i].size(); j++) {
			komponensek[i][j] -= n;
			if (igazsag_ertek[abs(komponensek[i][j])] != -1) {
				akt_igaz = igazsag_ertek[abs(komponensek[i][j])];
				if (komponensek[i][j] < 0) {
					akt_igaz = 1 - akt_igaz;
				}
			}
		}

		if (akt_igaz == -1) {
			akt_igaz = 1;
		}

		for (int j = 0; j  < komponensek[i].size() ; j++) {
			int index = abs(komponensek[i][j]);
			int ertek = komponensek[i][j] > 0 ? akt_igaz : !akt_igaz;
			if (igazsag_ertek[index] != -1 && igazsag_ertek[index] != ertek)
				return false;
			igazsag_ertek[index] = ertek;
		}
	}

	return true;
}


void dfs_scc(int n, vector<vector<int>>& graf, vector<int>& belep, vector<bool>& vermen, vector<int>& low, stack<int>& verem,
	vector<vector<int>>& komponensek, int& komponens, int& ido, int v) 
{
	ido++;
	belep[v] = ido;
	low[v] = ido;
	vermen[v] = true;
	verem.push(v);

	for (int i : graf[v]) {
		if (belep[i] == -1) {
			dfs_scc(n, graf, belep, vermen, low, verem, komponensek, komponens, ido, i);
			low[v] = min(low[v], low[i]);
		}
		else if ((belep[i] < belep[v]) && vermen[i]) {
			low[v] = min(low[v], belep[i]);
		}
	}

	if (low[v] == belep[v]) {
		komponens++;
		komponensek.resize(komponens);
		while (!verem.empty() && (belep[verem.top()] >= belep[v])) {
			komponensek[komponens - 1].push_back(verem.top());
			vermen[verem.top()] = false;
			verem.pop();
		}
	}
}