Cod sursa(job #372187)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 9 decembrie 2009 01:22:49
Problema 2SAT Scor Ascuns
Compilator cpp Status done
Runda Marime 2.99 kb
#include <fstream>
#include <vector>
#include <stack>
#include <cstring>
#define MAXN 100010
using namespace std;
ifstream fi("2sat.in");
ofstream fo("2sat.out");
int N,M;
vector< int > G[2][MAXN]; // G[0] - graf normal , G[1] - graf transpus
vector< int > GComp[MAXN]; // graful componentelor tare conexe
int WhatComp[MAXN],used[MAXN],NComps,usedComp[MAXN],assoc[MAXN],val[MAXN];
stack< int > S;
vector< vector< int > > Comps;


//introducem in graf o restrictie de tipul x sau y
//N-x+1 = ~x

void make_graph(int x, int y){
	G[0][N-x+1].push_back(y);
 	G[1][y].push_back(N-x+1);
	G[0][N-y+1].push_back(x);
	G[1][x].push_back(N-y+1);
}


void get_input(){
	int x,y,z;
	fi>>N>>M;
	N*=2;
	for (int i=1; i<=M; ++i){
		fi>>x>>y>>z;
		if (x<0) { x=-x; x=N-x+1; }
		if (y<0) { y=-y; y=N-y+1; }
		make_graph(x, y);
	}
	fi.close();
}

//parcurgerea +

void DFSPlus(int nod, vector<int>* G){
	used[nod]=1;
	vector<int>::iterator it;
	for (it=G[nod].begin(); it!=G[nod].end(); ++it)
		if (!used[*it]) DFSPlus(*it, G);
	S.push(nod);
}

//parcurgerea -

void DFSMinus(int nod, vector<int>* G, int componenta){
	WhatComp[nod]=componenta;
	vector<int>::iterator it;
	for (it=G[nod].begin(); it!=G[nod].end(); ++it)
		if (!WhatComp[*it]) DFSMinus(*it, G, componenta);
}

//sortare topologica

void topologica(int nod, vector<int>* G){
	used[nod]=1;
	vector<int>::iterator it;
	for (it=G[nod].begin(); it!=G[nod].end(); ++it)
		if (!used[*it]) topologica(*it, G);
	S.push(nod);
}

void get_output(){
	N/=2;
	for (int  i=1; i<N; ++i) fo<<val[i]<<" ";
	fo<<val[N]<<"\n";
	fo.close();
}


int main(){
	get_input();
	
	//determin componentele tare conexe
	memset(used, 0, sizeof(used));
	memset(WhatComp, 0, sizeof(WhatComp));
	for (int i=1; i<=N; ++i) if (!used[i]) DFSPlus(i, G[0]);

	NComps=0;
	while (!S.empty()){
		if (!WhatComp[S.top()]){ ++NComps; DFSMinus(S. top(),G[1],NComps); }
		S.pop();
	}
	Comps.resize(NComps+1);
	for (int i=1; i<=N; ++i) Comps[WhatComp[i]].push_back(i);

	//verific daca am solutie
	for (int i=1; i<=N; ++i) if (WhatComp[i]==WhatComp[N-i+1]){
		fo<<"-1\n";fo.close(); return 0;
	}

	//construiesc DAG-ul componentelor tare conexe
	for (int i=1; i<=N; ++i){
		memset(usedComp, 0, sizeof(usedComp));
		for (vector<int>::iterator it=G[0][i].begin(); it!=G[0][i].end(); ++it)
			if (WhatComp[i]!=WhatComp[*it] && !usedComp[WhatComp[*it]]){
				GComp[WhatComp[i]].push_back(WhatComp[*it]);
				usedComp[WhatComp[*it]]=1; // sa nu adaug acelasi vecin de 2 ori
			}
	}
	for (int i=1; i<=N; ++i) assoc[WhatComp[i]]=WhatComp[N-i+1]; // formez perechile de componente tare conexe

	//sortez DAG-ul topologic
	memset(used, 0, sizeof(used));
	for (int i=1; i<=NComps; ++i) 
		if (!used[i]) topologica(i,GComp);
	
	//caut solutia
	memset(used, 0, sizeof(used));
	memset(val, 0, sizeof(val));
	while (!S.empty()){
		if (!used[S.top()]){
			for (vector<int>::iterator it=Comps[S.top()].begin(); it!=Comps[S.top()].end(); ++it) { val[*it]=0; val[N-(*it)+1]=1; }
			used[S.top()]=1;
			used[assoc[S.top()]]=1;
		}
		S.pop();
	}

	
	get_output();

	return 0;
}