Cod sursa(job #85326)

Utilizator stef2nStefan Istrate stef2n Data 20 septembrie 2007 22:03:44
Problema Party Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
/*
 *	2SAT
 *	Complexitate: O(N+M)
 */

#include <cstdio>
#include <vector>
using namespace std;

#define NMAX 105
#define pb push_back
#define sz size()

int N,M;
vector <short int> L[2*NMAX];
vector <short int> T[2*NMAX]; // graful transpus
short int timp[2*NMAX],order[2*NMAX];
int next_time;
short int CTC[2*NMAX],cnt_ctc=0;

vector <short int> LCTC[2*NMAX];
short int timeCTC[2*NMAX];
vector <short int> sol;

inline short int opus(short int x)
{
	if(x<=N)
		return x+N;
	else
		return x-N;
}

inline void add(short int a, short int b)
{
	L[opus(a)].pb(b); T[b].pb(opus(a));
	L[opus(b)].pb(a); T[a].pb(opus(b));
}

void read_data()
{
	short int u,v,type;
	scanf("%d %d",&N,&M);
	for(int i=0;i<M;i++)
	{
		scanf("%hd %hd %hd",&u,&v,&type);
		switch(type)
		{
			case 0:	add(u,v);
				break;
			case 1:	add(u,opus(v));
				break;
			case 2:	add(opus(u),v);
				break;
			case 3: add(opus(u),opus(v));
				break;
		}
	}
}

void df1(int vertex)
{
	for(vector <short int>::iterator i=L[vertex].begin(); i!=L[vertex].end(); ++i)
		if(timp[*i]==-1) // ne-vizitat
		{
			timp[*i]=0; // vizitat
			df1(*i);
			++next_time;
		}
	timp[vertex]=next_time;
}

void df2(int vertex)
{
	for(vector <short int>::iterator i=T[vertex].begin(); i!=T[vertex].end(); ++i)
		if(!CTC[*i])
		{
			CTC[*i]=cnt_ctc;
			df2(*i);
		}
}

void df3(int vertex)
{
	for(vector <short int>::iterator i=LCTC[vertex].begin(); i!=LCTC[vertex].end(); ++i)
		if(timeCTC[*i]==-1) // ne-vizitat
		{
			timeCTC[*i]=0; // vizitat
			df3(*i);
			++next_time;
		}
	timeCTC[vertex]=next_time;
}


int main()
{
	freopen("party.in","r",stdin);
	freopen("party.out","w",stdout);
	read_data();
	// componente tare conexe
	int i;
	next_time=1;
	for(i=1;i<=2*N;i++)
		timp[i]=-1; // ne-vizitat
	for(i=1;i<=2*N;i++)
		if(timp[i]==-1)
		{
			timp[i]=0; // vizitat
			df1(i);
			++next_time;
		}
	for(i=1;i<=2*N;i++)
	{
		order[2*N-timp[i]+1]=i;
		CTC[i]=0;
	}
	for(i=1;i<=2*N;i++)
		if(!CTC[order[i]])
		{
			CTC[order[i]]=++cnt_ctc;
			df2(order[i]);
		}
	// construirea arborelui componentelor tare conexe
	for(i=1;i<=2*N;i++)
		for(vector <short int>::iterator it=L[i].begin(); it!=L[i].end(); ++it)
			if(CTC[i]!=CTC[*it])
				LCTC[CTC[i]].pb(CTC[*it]);
	next_time=1;
	for(i=1;i<=cnt_ctc;i++)
		timeCTC[i]=-1; // ne-vizitat
	for(i=1;i<=cnt_ctc;i++)
		if(timeCTC[i]==-1)
		{
			timeCTC[i]=0; // vizitat
			df3(i);
			++next_time;
		}
	// solutia
	for(i=1;i<=N;i++)
		if(timeCTC[CTC[i]]<timeCTC[CTC[opus(i)]])
			sol.pb(i);

//	printf("%d",(int)sol.sz);
//	for(vector <short int>::iterator it=sol.begin(); it!=sol.end(); ++it)
//		printf("\n%d",(int)(*it));
//	printf("23");

	return 0;
}