Cod sursa(job #1758901)

Utilizator valiro21Valentin Rosca valiro21 Data 18 septembrie 2016 00:57:24
Problema 2SAT Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

#define NMax 100000

using namespace std;

vector<int> v[2*NMax+500];
vector<int> v_m[2*NMax+500]; //mirror of v

vector<int> comp_nodes[NMax+100];
bool comp_val[NMax+100];
int comp[2*NMax+200];
int sol[2*NMax+200];
int viz[2*NMax+200];
int n, m;

#define v (v+NMax)
#define v_m (v_m+NMax)
#define viz (viz+NMax)
#define comp (comp+NMax)
#define sol (sol+NMax)

#define DEBUG false

void kosaraju_visit (int nod, vector<int> &q) {
	if (viz[nod]) return;

	viz[nod] = true;
	for (int i = 0; i < v[nod].size (); i++)
		kosaraju_visit(v[nod][i], q);
	q.push_back (nod);
}

void kosaraju_assign (int nod, int component) {
	if (comp[nod] != 0) return;
	
	//if (DEBUG) cout << nod << ' ';
	// node is not assigned -> assign it to current component
	comp[nod] = component;
	comp_nodes[component].push_back (nod);
	for (int i = 0; i < v_m[nod].size (); i++) {
		kosaraju_assign(v_m[nod][i], component);
	}
}

bool twosat () {
	vector<int> q;
	for (int i = -n; i <= n; i++) {
		if (i==0) continue;
		kosaraju_visit (i, q);
	}

	int nrc = 0; //number of components
	for (int i = q.size () - 1; i >= 0; i--) {
		int nod = q[i];
		if (DEBUG) cout << nod << " " << comp[nod] << " ";
		if (comp[nod] == 0) {
			if (DEBUG) cout << "entered";
			kosaraju_assign(nod, ++nrc);
			if (DEBUG) cout << '\n';
			comp_val[nrc] = 0;
		}
		if (DEBUG) cout << '\n';
	}
	
	if (!DEBUG) goto end_log;
	cout << "Number of components: " << nrc << '\n';
	cout << "queue: ";
	for (int i = 0; i < q.size (); i++)
		cout << q[i] << ' ';
	cout << '\n';

	for (int i = 1; i <= n; i++) {
		cout << i << ' ' << comp[i] << ' ' << comp[-i] << '\n';
	}
	end_log:

	//assert a player and it's negation are not in the same component
	for (int i = 1; i <= n; i++) {
		if (comp[i] == comp[-i])
			return false;
	}
	
	if (DEBUG) cout << "Start assigning!\n";
	for (int i = 1; i <= nrc; i++) {
		for (int j = 0; j < comp_nodes[i].size (); j++) {
			int nod = comp_nodes[i][j];
			
			//assign solution to node
			sol[nod] = comp_val[i];
			
			// assign opposite value to component of the negation
			comp_val[comp[-nod]] = 1 - comp_val[i];
		}
	}
	if (DEBUG) cout << "Finished twosat\n";
	return true;
}

int main ()
{
	ifstream fin ("2sat.in");
	ofstream fout ("2sat.out");
	
	fin >> n >> m;
	for (int i = 0; i < m; i++) {
		int x, y;
		fin >> x >> y;
		v[-x].push_back(y);
		v[-y].push_back(x);
		
		// mirror
		v_m[y].push_back (-x);
		v_m[x].push_back (-y);
	}

	if (twosat()) {
		for (int i = 1; i <= n; i++) {
			fout << sol[i] << ' ';
		}
	}
	else {
		fout <<-1<< '\n';
	}

	return 0;
}