APIO 2011 - Table Coloring
Author: Andi Qu
Explanation
TL;DR
If we view the grid as a graph, we get connected components. The answer is then either or and we use DSU or DFS to determine which one it is.
Intuition
Let if the cell is blue and otherwise. For convenience, also add a row 0 and column 0.
Firstly, notice that if we already know the color of 3 cells in a table, then we also know the last color.
From this, we get the recurrence
for all .
After analysing this recurrence, we find that we actually have
I made a helpful spreadsheet for you to visualise this.
Counting the colorings
Without loss of generality, let the cell be red (since its color doesn't change the answer). This means that without any already-colored cells, all cells and are independent.
However, an already-colored cell makes the 2 cells and depend on each other.
View the grid as a graph:
- All cells and are nodes.
- For each already-colored cell , add an edge between and with weight .
This creates connected components. The answer is thus either or . This is because each node in a connected component is dependent on the other nodes in that component and all connected components are independent. If it simply isn't possible to color the table, the answer is .
Checking Whether the Answer is
This problem then becomes checking whether there is an cycle with odd weight in the resulting graph, which we can answer efficiently using DSU or DFS.
One way to implement this is as follows. Since each already-colored cell determines whether the colors of the cells and are the same, we can instead split each node in our graph into 2 nodes (one for each color) and create edges between nodes with consistent colors. The answer is if two new nodes corresponding to the same original node are in the same connected component.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>#define FOR(i, x, y) for (int i = x; i < y; i++)using namespace std;const int MOD = 1e9;int x[100001], y[100001], cmp[400001];int find(int A) {while (A != cmp[A]) cmp[A] = cmp[cmp[A]], A = cmp[A];
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!