Cod sursa(job #517467)

Utilizator AndreyPAndrei Poenaru AndreyP Data 28 decembrie 2010 21:59:45
Problema Party Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <cstdio>
#include <vector>
#include <bitset>
#include <stack>
using namespace std;
#define N 210
#define pb push_back

int n,n1,nc;
vector< int > a[N],b[N];
vector< vector <int> > c;
int ind[N],indlow[N],indice;
int com[N];
bitset< N > inst,rez;
stack< int > st;
int deg[N];

template< class T>
inline T minim(T x,T y) {
	return ( (x<y) ? x : y);
}


inline int not(int x) {
	return ( (x<=n1) ? (x+n1) : (x-n1) );
}

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

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

void tarjan(int nod) {
	ind[nod] = indlow[nod] = (++indice);
	st.push(nod);
	inst[nod] = 1;

	int nod1;
	for(size_t i=0,lim=a[nod].size(); i<lim; ++i) {
		nod1 = a[nod][i];
		if(ind[nod1]==0) {
			tarjan(nod1);
			indlow[nod] = minim(indlow[nod],indlow[nod1]);
		} else
		if(inst[nod1]==1)
			indlow[nod] = minim(indlow[nod],indlow[nod1]);
	}

	if(ind[nod]==indlow[nod]) {
		++nc;
		c.resize(nc+1);
		do {
			nod1 = st.top();
			st.pop();
			c[nc].pb(nod1);
			com[nod1] = nc;
			inst[nod1] = 0;
		}while(nod!=nod1);
	}
}

inline void comprima() {
	int aux,nod;
	for(int i=1; i<=nc; ++i) {
		inst.reset();
		inst[i] = 1;
		for(size_t j=0,lim=c[i].size(); j<lim; ++j) {
			nod = c[i][j];
			for(size_t t=0,lim1=a[nod].size(); t<lim1; ++t) {
				aux = com[a[nod][t]];
				if(inst[aux]==1)
					continue;
				inst[aux] = 1;
				b[i].pb(aux);
				++deg[aux];
			}
		}
	}
}

inline void rezolva() {
	ind[0] = 0;
	inst.reset();
	for(int i=1; i<=nc; ++i) {
		if(deg[i]==0) {
			ind[++ind[0]] = i;
			inst[i] = 1;
			rez[i] = 0;
			inst[com[not(c[i][0])]] = 1;
			rez[com[not(c[i][0])]] = 1;
		}
	}

	int nod,nod1;
	for(int i=1; i<=ind[0]; ++i) {
		nod = ind[i];
		for(size_t j=0,lim=b[nod].size(); j<lim; ++j) {
			--deg[b[nod][j]];
			if(deg[b[nod][j]]==0 && inst[b[nod][j]]==0) {
				nod1 = b[nod][j];
				ind[++ind[0]] = nod1;
				inst[nod1] = 1;
				rez[nod1] = 0;
				inst[com[not(c[nod1][0])]] = 1;
				rez[com[not(c[nod1][0])]] = 1;
			}
		}
	}
}

inline void scrie() {
	int nrez = 0;
	for(int i=1; i<=n1; ++i) {
		if(rez[com[i]]==1)
			++nrez;
	}

	printf("%d\n",nrez);
	for(int i=1; i<=n1; ++i) {
		if(rez[com[i]]==1)
			printf("%d\n",i);
	}
}

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

	citire();
	for(int i=1; i<=n; ++i) {
		if(ind[i]==0)
			tarjan(i);
	}
	comprima();
	rezolva();
	scrie();

	return 0;
}