Cod sursa(job #1373007)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 4 martie 2015 16:18:10
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.75 kb
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <limits>
#include <algorithm>
using namespace std;

const unsigned INF = numeric_limits<unsigned>::max();

unsigned nrvar,nrexp;
vector< vector<unsigned> > AdjList;

vector< vector<unsigned> > sccs;
vector< unsigned > whichscc;

namespace Tarjan{
	std::vector<unsigned> index,lowlink;
	vector<bool> onstack;
	stack<unsigned> S;
	int cindex=1;

	void strongconnect(unsigned v){
		index[v]   = cindex;
		lowlink[v] = cindex;
		++cindex;

		S.push(v); onstack[v]=true;

		for(auto it=AdjList[v].begin();it!=AdjList[v].end();++it){
			const int &w = *it;
			if(index[w]==0){
				strongconnect(w);
				lowlink[v]=min(lowlink[v],lowlink[w]);
			}
			else if(onstack[w]) lowlink[v]=min(lowlink[v],index[w]);
		}

		if(lowlink[v]==index[v]){ //v is root of new scc
			int curr_scc_ind=sccs.size();
			vector<unsigned> cc;
			unsigned w;
			do{
				w=S.top(); S.pop();
				onstack[w]=false;
				cc.push_back(w);
				whichscc[w]=curr_scc_ind;
			} while(w!=v);
			sccs.push_back(cc);
		}
	}

	void compute_sccs(){
		index.resize(2*nrvar+1,0); lowlink.resize(2*nrvar+1);
		onstack.resize(2*nrvar+1,false);

		for(unsigned i=1;i<=2*nrvar;++i)
			if(index[i]==0) strongconnect(i);
	}
}



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

	fin>>nrvar>>nrexp;
	AdjList.resize(2*nrvar+1); //1..2*nrvar
	whichscc.resize(2*nrvar+1,INF);

	for(unsigned i=0;i<nrexp;++i){
		int a,b; fin>>a>>b;
		if(a<0) a=-a+nrvar;
		if(b<0)	b=-b+nrvar;
		AdjList[ ( (unsigned)a>nrvar)?(a-nrvar):(a+nrvar) ].push_back(b); //~a -> b
		AdjList[ ( (unsigned)b>nrvar)?(b-nrvar):(b+nrvar) ].push_back(a);	//~b -> a
	}

	Tarjan::compute_sccs();

	bool possible=true;
	for(unsigned i=1;i<=nrvar;++i)
		if(whichscc[i]==whichscc[i+nrvar]) possible=false;


	if(possible){
		vector<short> value(nrvar+1,-1);
		vector<unsigned> indegree(sccs.size(),0);

		for(unsigned i=1;i<=2*nrvar;++i)
			for(auto it=AdjList[i].begin();it!=AdjList[i].end();++it)
				if(whichscc[i]!=whichscc[*it]) ++indegree[ whichscc[*it] ];

		queue<unsigned> q;
		for(unsigned i=0;i<sccs.size();++i)
			if(indegree[i]==0) q.push(i);

		while(!q.empty()){
			int c=q.front(); q.pop();

			for(auto it=sccs[c].begin();it!=sccs[c].end();++it){
				int cv= *it>nrvar ? *it-nrvar : *it;
				if(value[cv]==-1){
					value[cv]= *it<=nrvar ? 0:1;
				}

				for(auto it2=AdjList[*it].begin();it2!=AdjList[*it].end();++it2)
					if(whichscc[*it]!=whichscc[*it2]){
						unsigned a = --indegree[whichscc[*it2]];
						if(a==0) q.push(whichscc[*it2]);
					}
			}

		}

		for(unsigned i=1;i<=nrvar;++i) fout<<value[i]<<' ';
		fout<<'\n';
	}
	else fout<<-1<<'\n';

	/*for(auto it=sccs.begin();it!=sccs.end();++it){
		for(auto it2=it->begin();it2!=it->end();++it2) fout<<*it2<<' ';
		fout<<'\n';
	}*/
}