Submission #218282

#TimeUsernameProblemLanguageResultExecution timeMemory
218282dolphingarlicSkandi (COCI20_skandi)C++14
110 / 110
103 ms23208 KiB
/* COCI 2020 Skandi - If we view horizontal and vertical words as nodes in a graph and connect words if they intersect, we get a bipartite graph - The problem now becomes finding the minimum vertex cover of this graph - By Konig's theorem, this is equal to the maximum bipartite matching - We can use the Hopcraft-Karp algorithm for this - To construct the vertex cover, we do a DFS and magic happens - Complexity: O(N^3) */ #include <bits/stdc++.h> #define FOR(i, x, y) for (int i = x; i < y; i++) typedef long long ll; using namespace std; bool dfs(int a, int L, vector<vector<int>>& g, vector<int>& btoa, vector<int>& A, vector<int>& B) { if (A[a] != L) return 0; A[a] = -1; for (int b : g[a]) if (B[b] == L + 1) { B[b] = 0; if (btoa[b] == -1 || dfs(btoa[b], L + 1, g, btoa, A, B)) return btoa[b] = a, 1; } return 0; } int hopcroftKarp(vector<vector<int>>& g, vector<int>& btoa) { int res = 0; vector<int> A(g.size()), B(btoa.size()), cur, next; for (;;) { fill(A.begin(), A.end(), 0); fill(B.begin(), B.end(), 0); /// Find the starting nodes for BFS (i.e. layer 0). cur.clear(); for (int a : btoa) if(a != -1) A[a] = -1; FOR(a, 0, g.size()) if(A[a] == 0) cur.push_back(a); /// Find all layers using bfs. for (int lay = 1;; lay++) { bool islast = 0; next.clear(); for (int a : cur) for (int b : g[a]) { if (btoa[b] == -1) { B[b] = lay; islast = 1; } else if (btoa[b] != a && !B[b]) { B[b] = lay; next.push_back(btoa[b]); } } if (islast) break; if (next.empty()) return res; for (int a : next) A[a] = lay; cur.swap(next); } /// Use DFS to scan for augmenting paths. FOR(a, 0, g.size()) res += dfs(a, 0, g, btoa, A, B); } } char grid[501][501]; int c_horiz[501][501], c_vert[501][501], horiz = 0, vert = 0; vector<pair<int, int>> horiz_loc, vert_loc; bool visited[500001], has_edge[250001]; vector<int> graph[500001]; void fvc(int node) { visited[node] = true; for (int i : graph[node]) if (!visited[i]) fvc(i); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, m; cin >> n >> m; FOR(i, 1, n + 1) FOR(j, 1, m + 1) { cin >> grid[i][j]; if (grid[i][j] == '0') { if (grid[i][j - 1] == '1') { c_horiz[i][j] = horiz++; horiz_loc.push_back({i, j - 1}); } else c_horiz[i][j] = c_horiz[i][j - 1]; if (grid[i - 1][j] == '1') { c_vert[i][j] = vert++; vert_loc.push_back({i - 1, j}); } else c_vert[i][j] = c_vert[i - 1][j]; } } vector<vector<int>> g(vert); FOR(i, 1, n + 1) FOR(j, 1, m + 1) { if (grid[i][j] == '0') g[c_vert[i][j]].push_back(c_horiz[i][j]); } vector<int> btoa(horiz, -1); cout << hopcroftKarp(g, btoa) << '\n'; FOR(i, 0, vert) for (int j : g[i]) { if (btoa[j] == i) { graph[vert + j].push_back(i); has_edge[i] = true; } else graph[i].push_back(vert + j); } FOR(i, 0, vert) if (!has_edge[i] && !visited[i]) fvc(i); FOR(i, 0, vert) if (!visited[i]) cout << vert_loc[i].first << ' ' << vert_loc[i].second << " DOLJE\n"; FOR(i, 0, horiz) if (visited[vert + i]) cout << horiz_loc[i].first << ' ' << horiz_loc[i].second << " DESNO\n"; return 0; }

Compilation message (stderr)

skandi.cpp: In function 'int hopcroftKarp(std::vector<std::vector<int> >&, std::vector<int>&)':
skandi.cpp:13:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, x, y) for (int i = x; i < y; i++)
skandi.cpp:37:13:
         FOR(a, 0, g.size()) if(A[a] == 0) cur.push_back(a);
             ~~~~~~~~~~~~~~              
skandi.cpp:37:9: note: in expansion of macro 'FOR'
         FOR(a, 0, g.size()) if(A[a] == 0) cur.push_back(a);
         ^~~
skandi.cpp:13:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, x, y) for (int i = x; i < y; i++)
skandi.cpp:58:13:
         FOR(a, 0, g.size())
             ~~~~~~~~~~~~~~              
skandi.cpp:58:9: note: in expansion of macro 'FOR'
         FOR(a, 0, g.size())
         ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...