Cod sursa(job #59760)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 10 mai 2007 12:17:53
Problema Party Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <cstdio>
#include <cstring>

const int NMAX = 256;

int N, M, T, NS, NC, sol;
bool G[NMAX][NMAX], V[NMAX], U[NMAX][NMAX], out[NMAX];
int conex[NMAX], stk[NMAX], in[NMAX];

void read(void) {
	FILE *fin = fopen("party.in", "rt");
	int i, u, v, z;

	fscanf(fin, " %d %d", &N, &M);

	T = N << 1;

	for (i = 0; i < M; ++i) {
		fscanf(fin, " %d %d %d", &u, &v, &z);

		switch(z) {
			case 0: G[N + u][v] = G[N + v][u] = true; break;
			case 1: G[N + u][N + v] = G[v][u] = true; break;
			case 2: G[u][v] = G[N + v][N + u] = true; break;
			case 3: G[u][N + v] = G[v][N + u] = true; break;
		}
	}

	fclose(fin);
}

void DFS1(int k) {
	int i;

	V[k] = true;
	for (i = 1; i <= T; ++i)
		if (!V[i] && G[k][i])
			DFS1(i);
	stk[NS++] = k;
}

void DFS2(int k) {
	int i;

	V[k] = true;
	conex[k] = NC;
	for (i = 1; i <= T; ++i)
		if (!V[i] && G[i][k])
			DFS2(i);
}

void connect(void) {
	int i, j, u, cu;

	for (i = 1; i <= T; ++i)
		if (!V[i]) DFS1(i);
	
	memset(V, 0x00, sizeof(V));
	for (i = NS - 1; i >= 0; --i)
		if (!V[stk[i]]) {
			++NC;
			DFS2(stk[i]);
		}

	for (i = 1; i <= T; ++i)
		for (j = 1; j <= T; ++j)
			if (conex[i] != conex[j] && G[i][j]) {
				U[conex[i]][conex[j]] = true;
				++in[conex[j]];
			}
	
	NS = 0;
	for (i = 1; i <= NC; ++i)
		if (in[i] == 0)
			stk[NS++] = i;
	
	for (i = 0; i < NS; ++i) {
//		printf("stk %d\n", stk[i]);
		u = stk[i]; cu = u <= N ? u + N : u - N;

		if (!out[u] && !out[cu]) {
			out[u] = true;

			for (j = 1; j <= NC; ++j)
				if (U[u][j] && --in[j] == 0)
					stk[NS++] = j;
		}
	}
}

void write(void) {
	FILE *fout = fopen("party.out", "wt");
	int i;
	
	for (i = 1; i <= N; ++i)
		if (!out[conex[i]])
			++sol;

	fprintf(fout, "%d\n", sol);

	for (i = 1; i <= N; ++i)
		if (!out[conex[i]])
			fprintf(fout, "%d\n", i);

	fclose(fout);
}

int main(void) {
	
	read();

	connect();

	write();

	return 0;
}