Cod sursa(job #468439)

Utilizator AndreyPAndrei Poenaru AndreyP Data 3 iulie 2010 17:01:44
Problema Andrei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <cstdio>
#include <bitset>
#include <vector>
#include <algorithm>
using namespace std;
#define pb push_back
#define N 100005

int n,n1;
vector< int > a[N<<1],b[N<<1];
int st[N<<1];
bitset< N<<1 > inst;
bitset< N<<1 > rez;
bitset< N<<1 > gotRez;
vector< vector< int > > c;
int ind[N<<1],indlow[N<<1],inde;
int nrc[N<<1];
int deg[N<<1];
int v[N<<1];
int nrcom;

inline void citire()
{
	int m;
	scanf("%d%d",&n,&m);
	n1=n<<1;
	int x,y,c;

	for(int i=0; i<m; ++i)
	{
		scanf("%d%d%d",&x,&y,&c);
		if(c==0)
		{
			a[x+n].pb(y);
			a[y+n].pb(x);
			continue;
		}
		if(c==1)
		{
			a[x].pb(y+n);
			a[y].pb(x+n);
			continue;
		}
		a[x].pb(y);
		a[y+n].pb(x+n);
		a[x+n].pb(y+n);
		a[y].pb(x);
	}
}

void tarjan(int nod)
{
	ind[nod]=indlow[nod]=++inde;
	st[++st[0]]=nod;
	inst[nod]=1;

	for(vector< int >::iterator it=a[nod].begin(),lim=a[nod].end(); it!=lim; ++it)
	{
		if(ind[*it]==0)
		{
			tarjan(*it);
			if(indlow[nod]>indlow[*it])
				indlow[nod]=indlow[*it];
		}
		else
		{
			if(inst[*it]==1)
			{
				if(indlow[nod]>indlow[*it])
					indlow[nod]=indlow[*it];
			}
		}
	}

	if(ind[nod]==indlow[nod])
	{
		int aux=c.size();
		c.resize(aux+1);
		int nod1;
		do
		{
			nod1=st[st[0]];
			--st[0];
			c[aux].pb(nod1);
			nrc[nod1]=aux;
			inst[nod1]=0;
		}while(nod1!=nod);
	}
}

inline void adauga(int cn)
{
	inst.reset();
	inst[cn]=1;
	for(vector< int >::iterator it=c[cn].begin(),lim=c[cn].end(); it!=lim; ++it)
	{
		for(vector< int >::iterator it1=a[*it].begin(),lim1=a[*it].end(); it1!=lim1; ++it1)
		{
			if(inst[nrc[*it1]]==1)
				continue;
			inst[nrc[*it1]]=1;
			++deg[nrc[*it1]];
			b[cn].pb(nrc[*it1]);
		}
	}
}

inline void compactez()
{
	for(int i=1; i<=n1; ++i)
	{
		if(ind[i])
			continue;
		tarjan(i);
	}

	nrcom=c.size();
	for(int i=0; i<nrcom; ++i)
		adauga(i);
}

inline void rezolva()
{
	for(int i=0; i<nrcom; ++i)
	{
		if(deg[i]==0)
			v[++v[0]]=i;
	}

	int x,y;
	for(int i=1; i<=v[0]; ++i)
	{
		x=v[i];
		for(vector< int >::iterator it=b[x].begin(),lim=b[x].end(); it!=lim; ++it)
		{
			--deg[*it];
			if(deg[*it]==0)
				v[++v[0]]=*it;
		}

		if(gotRez[x]==1)
			continue;
		y=c[x].front();
		gotRez[x]=1;
		rez[x]=0;
		if(y<=n)
			y+=n;
		else
			y-=n;
		gotRez[nrc[y]]=1;
		rez[nrc[y]]=1;
	}
}

inline void scrie()
{
	for(int i=1; i<n; ++i)
	{
		fputc(( (rez[nrc[i]]==0) ? '0' : '1'),stdout);
		fputc(' ',stdout);
	}

	fputc(( (rez[nrc[n]]==0) ? '0' : '1'),stdout);
	fputc('\n',stdout);
}

int main()
{
	freopen("andrei.in","r",stdin);
	freopen("andrei.out","w",stdout);

	citire();
	compactez();
	rezolva();
	scrie();

	return 0;
}