Cod sursa(job #2298231)

Utilizator danielsociuSociu Daniel danielsociu Data 7 decembrie 2018 19:47:08
Problema 2SAT Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <stack>
using namespace std;
ifstream cin("2sat.in");
ofstream cout("2sat.out");
#define pb push_back
#define mk make_pair
#define maxn 200005
#define minim(a,b) a<b?a:b

vector<int> g[maxn];
int sol[maxn/2];
int n,m;

inline int change(int x) {return(x<0)?(abs(x)+n):x; }
inline int changesecond(int x) {return(x<0)?abs(x):x+n;}
inline int check(int x) {return (x>n)?x-n:x;}
inline int solve(int x) {return (x>n)?1:0;}

stack<int> q;
int viz[maxn],link[maxn],in_stack[maxn];
int indecs;
void tarjan(int x);
int poz[maxn];
vector<int> actual;
vector<vector<int> > comp;

int main()
{
		int x,y;
		cin>>n>>m;
		for(;m--;){
			cin>>x>>y;
			g[changesecond(x)].pb(change(y));
			g[changesecond(y)].pb(change(x));
		}
		for(int i=1;i<=2*n;i++)
			if(!viz[i])
				tarjan(i);
		for(int i=1;i<=n;i++)
			if(poz[i]==poz[i+n]){
				cout<<"-1"; return 0;
			}
		memset(sol,-1,sizeof(sol));
		for(int i=comp.size()-1;i>=0;i--){
			for(auto it=comp[i].begin();it!=comp[i].end();it++){
				if(sol[check(*it)]==-1)
					sol[check(*it)]=solve(*it);
			}
		}
		for(int i=1;i<=n;i++)
			cout<<sol[i]<<' ';
		return 0;
}

void tarjan(int x)
{
		viz[x]=link[x]=++indecs;
		in_stack[x]=1; q.push(x);
		for(auto it=g[x].begin();it!=g[x].end();it++){
			if(!viz[*it]){
				tarjan(*it);
				link[x]=minim(link[x],link[*it]);
			}else if (in_stack[*it])
				link[x]=minim(link[x],link[*it]);
		}
		if(viz[x]==link[x]){
			actual.clear();
			int nod;
			do{
				nod=q.top();
				actual.push_back(nod);
				q.pop();
				in_stack[nod]=0;
			}while(nod!=x);
			comp.push_back(actual);
			for(auto it=actual.begin();it!=actual.end();it++)
			{
				poz[*it]=comp.size();
			}
		}
}