Skip to content

Commit a415b56

Browse files
APIO 11-color
1 parent 90b5070 commit a415b56

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

APIO/APIO 11-Color.cpp

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// USACO Guide has a slightly different solution
2+
// Note that the entire grid is dependent on the first row and the first column
3+
// The cell (i, j) is dependent on (1, 1), (1, j), and (i, 1)
4+
// Therefore, make a graph: 0...n-1 represents (i, 1). n...n+m-1 represents(1, j).
5+
// For every cell that's already colored in, draw an edge between the row and the column nodes it's dependent on
6+
// Mark the edge as "these two nodes have the same value" or "these two nodes have different values" depending on the value of the cell
7+
// Set (1, 1) to red and calculate the # of valid assignments
8+
// Set (1, 1) to blue and calculate the # of valid assignments
9+
// To calculate # of valid assignments, we basically DFS from every node (beginning from the nodes whose values we already know).
10+
// Set the values of all connected nodes.
11+
// For nodes whose values we don't know, just arbitrarily assign a value and multiply the # of valid assignments by 2.
12+
13+
#include <bits/stdc++.h>
14+
15+
using namespace std;
16+
17+
using ll = long long;
18+
#define ii pair<int, int>
19+
#define f first
20+
#define s second
21+
#define pb push_back
22+
#define mp make_pair
23+
#define all(x) x.begin(), x.end()
24+
#define sz(x) (int)x.size()
25+
#define F0R(i, n) for (int i = 0; i < n; i++)
26+
#define FOR(i, a, b) for (int i = a; i < b; i++)
27+
#define inf 1000000010
28+
29+
// [0...n-1] is rows
30+
// [n...n+m-1] is columns
31+
// n+m is 0
32+
// n+m+1 is 1
33+
// second: 1 if not equal, 0 if equal
34+
vector<ii> adj[300000];
35+
int color[300000];
36+
bool vis[300000];
37+
int topLeftC;
38+
39+
ll ans = 1;
40+
41+
void dfs(int u) {
42+
if (vis[u]) return;
43+
vis[u] = true;
44+
if (color[u] == -1) {
45+
//cerr << u << endl;
46+
ans = (ans*2)%((int)1e9);
47+
color[u] = 0;
48+
}
49+
for (ii v : adj[u]) {
50+
int expected = color[u] ^ v.s ^ topLeftC;
51+
if (color[v.f] == -1) color[v.f] = expected;
52+
if (color[v.f] != expected) {
53+
ans = 0;
54+
}
55+
dfs(v.f);
56+
}
57+
}
58+
59+
int main() {
60+
cin.tie(0)->sync_with_stdio(0);
61+
62+
int n, m, k; cin >> n >> m >> k;
63+
int topLeft = -1;
64+
color[n+m] = 0;
65+
color[n+m+1] = 1;
66+
for (int i = 0; i < k; i++) {
67+
int x, y, c; cin >> x >> y >> c;
68+
if (x == y && x == 1) {
69+
topLeft = c;
70+
} else if (x == 1) {
71+
adj[n+y-1].emplace_back(n+m+c, 0);
72+
adj[n+m+c].emplace_back(n+y-1, 0);
73+
} else if (y == 1) {
74+
adj[x-1].emplace_back(n+m+c, 0);
75+
adj[n+m+c].emplace_back(x-1, 0);
76+
} else {
77+
if (x%2==0 && y%2==0) {
78+
c ^= 1;
79+
}
80+
int r = x-1, col = n+y-1;
81+
adj[r].pb(mp(col, c));
82+
adj[col].pb(mp(r, c));
83+
}
84+
}
85+
86+
ll totAns = 0;
87+
for (topLeftC = 0; topLeftC <= 1; topLeftC++) {
88+
if (topLeft != -1 && topLeft != topLeftC) continue;
89+
ans = 1;
90+
for (int i = 0; i < n+m; i++) {
91+
color[i] = -1;
92+
}
93+
for (int i = 0; i < n+m+10; i++) {
94+
vis[i] = false;
95+
}
96+
dfs(n+m);
97+
dfs(n+m+1);
98+
for (int i = 0; i < n+m; i++) {
99+
if (i == 0 || i == n) continue; // these point to the upper left cell that's a special case
100+
dfs(i);
101+
}
102+
totAns = (totAns + ans) % ((int)1e9);
103+
}
104+
105+
106+
cout << totAns << endl;
107+
108+
return 0;
109+
}

0 commit comments

Comments
 (0)