#include <stdio.h> short T[1001][1000], N[1001][1000]; short Tc[1001], Nc[1001], P[1001], F[1001]; int C[1001]; int FC = 1; int n, m; int left; int Find (int i) { int j; for (j = i; F[j] >= 0; j = F[j]) {}; while (F[i] >= 0) { int k = F[i]; F[i] = j; i = k; } return j; } int Merge (int i, int j) { i = Find(i); j = Find(j); if (i == j) return; if (F[i] < F[j]) { F[i] += F[j]; F[j] = i; return i; } else { F[j] += F[i]; F[i] = j; return j; } } int solve (int ceo, int color) { int i, j, FC0, FC1; int total_found = 0; for (;;) { int found = 0; for (i = 1; i <= n; ++i) if (C[i] == color) { int ok = 1; for (j = 0; j < Tc[i]; ++j) if (C[T[i][j]] == color) { ok = 0; break; } if (!ok) continue; for (j = 0; j < Nc[i]; ++j) if (C[N[i][j]] == color) { ok = 0; break; } if (!ok) continue; ++found; P[i] = 1 + ceo; ceo = i; C[i] = -1; if (!--left) return 1; } if (!found) break; total_found += found; } if (!total_found) return 0; for (i = 1; i <= n; ++i) if (C[i] == color) F[i] = -1; for (i = 1; i <= n; ++i) if (C[i] == color) for (j = 0; j < Tc[i]; ++j) { int k = T[i][j]; if (C[k] == color) Merge(i, k); } FC0 = FC; for (i = 1; i <= n; ++i) if (C[i] == color) { int k = Find(i); if (C[k] == color) C[k] = FC++; C[i] = C[k]; } FC1 = FC; for (i = FC0; i < FC1; ++i) if (!solve(ceo, i)) return 0; return 1; } int main (void) { scanf("%d%d", &n, &m); while (m--) { int a, b; char c; scanf("%d%d %c", &a, &b, &c); if (c == 'T') T[a][Tc[a]++] = b; else N[b][Nc[b]++] = a; } left = n; if (solve(0, 0)) for (m = 1; m <= n; ++m) printf("%d\n", P[m] - 1); else printf("NIE\n"); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #include <stdio.h> short T[1001][1000], N[1001][1000]; short Tc[1001], Nc[1001], P[1001], F[1001]; int C[1001]; int FC = 1; int n, m; int left; int Find (int i) { int j; for (j = i; F[j] >= 0; j = F[j]) {}; while (F[i] >= 0) { int k = F[i]; F[i] = j; i = k; } return j; } int Merge (int i, int j) { i = Find(i); j = Find(j); if (i == j) return; if (F[i] < F[j]) { F[i] += F[j]; F[j] = i; return i; } else { F[j] += F[i]; F[i] = j; return j; } } int solve (int ceo, int color) { int i, j, FC0, FC1; int total_found = 0; for (;;) { int found = 0; for (i = 1; i <= n; ++i) if (C[i] == color) { int ok = 1; for (j = 0; j < Tc[i]; ++j) if (C[T[i][j]] == color) { ok = 0; break; } if (!ok) continue; for (j = 0; j < Nc[i]; ++j) if (C[N[i][j]] == color) { ok = 0; break; } if (!ok) continue; ++found; P[i] = 1 + ceo; ceo = i; C[i] = -1; if (!--left) return 1; } if (!found) break; total_found += found; } if (!total_found) return 0; for (i = 1; i <= n; ++i) if (C[i] == color) F[i] = -1; for (i = 1; i <= n; ++i) if (C[i] == color) for (j = 0; j < Tc[i]; ++j) { int k = T[i][j]; if (C[k] == color) Merge(i, k); } FC0 = FC; for (i = 1; i <= n; ++i) if (C[i] == color) { int k = Find(i); if (C[k] == color) C[k] = FC++; C[i] = C[k]; } FC1 = FC; for (i = FC0; i < FC1; ++i) if (!solve(ceo, i)) return 0; return 1; } int main (void) { scanf("%d%d", &n, &m); while (m--) { int a, b; char c; scanf("%d%d %c", &a, &b, &c); if (c == 'T') T[a][Tc[a]++] = b; else N[b][Nc[b]++] = a; } left = n; if (solve(0, 0)) for (m = 1; m <= n; ++m) printf("%d\n", P[m] - 1); else printf("NIE\n"); return 0; } |