Cod sursa(job #454845)

Utilizator nandoLicker Nandor nando Data 12 mai 2010 17:40:16
Problema 2SAT Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include <cstdio>
#include <vector>
#include <bitset>
#include <stack>
#include <set>
using namespace std;

#define NMAX 200010
typedef vector<int>::iterator iter;
typedef set<int>::iterator siter;

int n,m,idx[NMAX],llink[NMAX],comp[NMAX],ts[NMAX],nidx=1,nc=0,tcnt;
vector<int> g[NMAX];
vector<vector<int > > cc;
bitset<NMAX> inStack, val,viz;
stack<int> stk;
set <int> ng[NMAX];


void toNode(int& x){
	if(x<0){
		x=abs(x)+n;
	}
}

int notn(int x){
	return (x>n)?(x-n):(x+n);
}
 
void tarjan(int nod){
	idx[nod]=llink[nod]=nidx++;
	stk.push(nod),inStack[nod]=true;
	
	for(iter it=g[nod].begin();it!=g[nod].end();++it){
		if(!idx[*it]){
			tarjan(*it);
			llink[nod]=min(llink[nod],llink[*it]);
		}else if(inStack[*it]){
			llink[nod]=min(llink[nod],llink[*it]);
		}
	}
	if(idx[nod]==llink[nod]){
		vector<int> con;                      
		int nd;
		do{
			con.push_back(nd=stk.top());
			stk.pop(),inStack[nd]=false;
			comp[nd]=nc;
		}while(nd!=nod);
		cc.push_back(con);
		nc++;
	}	
}

void build(){
	for(int i=0;i<nc;i++){
		for(int j=0;j<cc[i].size();j++){
			for(iter it=g[cc[i][j]].begin();it!=g[cc[i][j]].end();++it){
				ng[i].insert(comp[*it]);	
			}
		}	
	}	
}

void tsort(int i){
	viz[i]=true;
	for(siter it=ng[i].begin();it!=ng[i].end();it++){
		if(!viz[*it]){
			tsort(*it);	
		}
	}
	ts[--tcnt]=i;
}

bool verif(){
	for(int i=1;i<=n;i++){
		if(comp[i]==comp[notn(i)]){
			return false;
		}	
	}
	return true;
}

void solve(int c){
	if(viz[c]){
		for(iter it=cc[c].begin();it!=cc[c].end();it++){
			val[*it]=0;
			val[notn(*it)]=1;
			viz[comp[notn(*it)]]=false;	
		}
	}	
}

int main(){
	FILE* fin=fopen("2sat.in","r");
	FILE* fout=fopen("2sat.out","w");
	
	fscanf(fin,"%d %d\n",&n,&m);
	
	for(int i=0,xi,xj;i<m;i++){
		fscanf(fin,"%d %d\n",&xi,&xj);
		toNode(xi),toNode(xj);
		
		g[notn(xi)].push_back(xj);
		g[notn(xj)].push_back(xi);
	}
	
	//determinam componentele tare conexe	
	for(int i=1;i<=n+n;i++){
		if(!idx[i]){
			tarjan(i);
		}
	}
	
	//daca nu avem contradictie...
	if(verif()){
		
		//construim noul graf
		build();
		
		//sortam topologic
		tcnt=nc;
		for(int i=0;i<nc;i++){
			if(!viz[i]){
				tsort(i);
			}	
		}
		for(int i=0;i<nc;i++){
			solve(ts[i]);	
		}
				
		for(int i=1;i<=n;i++){
			fprintf(fout,"%d ",val[i]==1);
		}	
	}else{
		fprintf(fout,"-1\n");	
	}
	fclose(fin);
	fclose(fout);
	return 0;
}