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
| const int MAXnd = MAXn * 2; const int MAXeg = MAXm * 2; int head[MAXnd + 10], cntnex, nex[MAXeg + 10], to[MAXeg + 10]; inline void Insert(int u, int v) { nex[++cntnex] = head[u]; head[u] = cntnex; to[cntnex] = v; }
int cntdfs, dfs[MAXnd + 10], low[MAXnd + 10]; int cntscc, inscc[MAXnd + 10]; vector<int> scc[MAXnd + 10]; int top, stk[MAXnd + 10]; bool instk[MAXnd + 10]; void Tarjan(int cur) { dfs[cur] = low[cur] = ++cntdfs; stk[++top] = cur; instk[cur] = 1; for (int i = head[cur]; i; i = nex[i]) { if (dfs[to[i]] == 0) { Tarjan(to[i]); low[cur] = min(low[cur], low[to[i]]); } else if (instk[to[i]]) { low[cur] = min(low[cur], dfs[to[i]]); } } if (dfs[cur] == low[cur]) { ++cntscc; int x; do { x = stk[top--]; instk[x] = 0; inscc[x] = cntscc; scc[cntscc].push_back(x); } while (x != cur); } }
int n, m, N; inline int otherside(int x) { if (x > n) return x - n; else return x + n; }
bool chosescc[MAXnd + 10]; bool chosen[MAXn + 10]; signed main() { read(n, m); N = n * 2; for (int i = 1, x, a, y, b; i <= m; ++i) { read(x, a, y, b); Insert(a ? x : x + n, b ? y + n : y); Insert(b ? y : y + n, a ? x + n : x); } for (int i = 1; i <= N; ++i) { if (dfs[i] == 0) { Tarjan(i); } } for (int i = 1; i <= n; ++i) { if (inscc[i] == inscc[n + i]) { puts("IMPOSSIBLE"); return 0; } } puts("POSSIBLE"); for (int i = 1; i <= cntscc; ++i) { if (chosescc[inscc[otherside(scc[i][0])]] == 0) { chosescc[i] = 1; } } for (int i = 1; i <= cntscc; ++i) { if (chosescc[i]) { for (auto j: scc[i]) { if (j > n) { chosen[j - n] = 1; } } } } for (int i = 1; i <= n; ++i) { printf("%d ", chosen[i]); } puts(""); return 0; }
|