Cod sursa(job #383676)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 17 ianuarie 2010 17:06:55
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include<stdio.h>
#include<vector>
#define non(x) x<=n?x+n:x-n
#define nod(x) x>0?x:n-x
#define NN 200010
using namespace std;
vector<int> succ[NN],prec[NN],S,T[NN];
int n,m,NC,c,viz[NN],C[NN],D[NN],L[NN],dfn,Gi[NN],Go[NN],CP[NN],
nedef=2,fals=0,adevarat=1,mark[NN];
void read(),solve(),visit(int p),CTC(),GR_CTC(),MARK_CTC();
int main()
{
	read();
	solve();
	return 0;
}
void read()
{
	int i,x,y,X,Y;
	freopen("2sat.in","r",stdin);
	freopen("2sat.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		x=nod(x);X=non(x);
		y=nod(y);Y=non(y);
		succ[X].push_back(y);prec[y].push_back(X);
		succ[Y].push_back(x);prec[x].push_back(Y);
	}
}
void solve()
{
	CTC();
	GR_CTC();
	MARK_CTC();
	for(int i=1;i<=n;i++)printf("%d ",L[i]);
	printf("\n");
}
void CTC()
{
	int i,j;
	for(i=1;i<=2*n;i++)
		if(!viz[i])
		{
			dfn=0;
			visit(i);
		}
	for(i=1;i<=NC;i++)
		if(!CP[i])
		{
			j=T[i].front();j=non(j);j=C[j];
			CP[i]=j;
			CP[j]=i;
		}
}
void visit(int p)
{   
	vector<int>::iterator it;
	viz[p]=1;S.push_back(p);dfn++;D[p]=dfn;L[p]=dfn;
    for(it=succ[p].begin();it!=succ[p].end();it++)
    {
		if(!viz[*it])
			visit(*it);
	    L[p]=(L[p]<L[*it])?L[p]:L[*it];
    }
    if(L[p]==D[p])
    {
		NC++;
		for(;;)
		{
			if(S.empty())break;
			if(L[S.back()]-L[p])break;
			T[NC].push_back(S.back());
			C[S.back()]=NC;
			S.pop_back();
		}
	}
}
void GR_CTC()
{
	int i;
	vector<int>::iterator it;
	for(i=1;i<=2*n;i++)
	{
		for(it=succ[i].begin();it!=succ[i].end();it++)
		{
			if(C[i]==C[*it])continue;
			Gi[C[*it]]++;Go[C[i]]++;
		}
	}
	for(i=1;i<=NC;i++)
	{
		if(Go[i]==0)S.push_back(i);
	}
}
void MARK_CTC()
{
	int i;
	vector<int>::iterator it,I,J;
	for(i=1;i<=NC;i++)mark[i]=nedef;
	for(it=S.begin();it!=S.end();it++)
	{
		if(mark[*it]==nedef)
		{
			mark[*it]=adevarat;
			mark[CP[*it]]=fals;
		}
		for(I=T[*it].begin();I!=T[*it].end();I++)
			for(J=prec[*I].begin();J!=prec[*I].end();J++)
			{
				if(C[*I]==C[*J])continue;
				Gi[C[*I]]--;Go[C[*J]]--;
				if(Go[C[*J]]==0)S.push_back(C[*J]);
			}
	}
	for(i=1;i<=NC;i++)
		for(it=T[i].begin();it!=T[i].end();it++)
			L[*it]=mark[i];
}