Submission #639564

#TimeUsernameProblemLanguageResultExecution timeMemory
639564Valaki2T-Covering (eJOI19_covering)C++14
100 / 100
172 ms31416 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define pb push_back #define mp make_pair #define pii pair<int, int> #define fi first #define se second #define vv(t) vector<vector<t> > #define assi(t, t2) (t2).assign(1 + n + 1, vector<t> (1 + m + 1, 0)) const int inf0 = 1e3 + 42; const vector<pii > dir4 {{1, 0}, {0, 1}, {0, -1}, {-1, 0}}; const vector<pii > dir2 {{2, 0}, {0, 2}, {0, -2}, {-2, 0}}; const vector<pii > dirdia {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}}; int ans; void no() { cout << "No\n"; exit(0); } void answer() { cout << ans << "\n"; exit(0); } struct dfs_ret { int adj_sum, adj_cnt, spec_cnt, min_leaf; }; int n, m, k; vv(int) val; vv(bool) filled; vv(int) center; vector<pii > coords; vector<bool> done; int get_adj4_cnt(const pii &p) { int res = 0; for(const pii &d : dir4) { if(!filled[d.fi + p.fi][d.se + p.se]) { res++; } } return res; } inline pii add(pii a, pii b) { return mp(a.fi + b.fi, a.se + b.se); } inline pii between(pii a, pii b) { return mp((a.fi + b.fi) / 2, (a.se + b.se) / 2); } void try_extend(int first_idx) { if(done[first_idx]) { return; } vector<int> indices; indices.pb(first_idx); vector<pii> fills; while(!indices.empty()) { for(int idx : indices) { if(done[idx]) { continue; } int cnt = get_adj4_cnt(coords[idx]); if(cnt == 4) { continue; } if(cnt < 3) { no(); } done[idx] = true; for(const pii &d : dir4) { pii nei = add(d, coords[idx]); if(!filled[nei.fi][nei.se]) { filled[nei.fi][nei.se] = true; ans += val[nei.fi][nei.se]; fills.pb(nei); } } } indices.clear(); for(pii cur : fills) { for(const pii &d : dir4) { pii nei = add(d, cur); if(center[nei.fi][nei.se] && !done[center[nei.fi][nei.se]]) { indices.pb(center[nei.fi][nei.se]); } } } fills.clear(); } } dfs_ret dfs(int idx, int par) { dfs_ret res = {0, 0, 1, inf0}; const pii &ci = coords[idx]; done[idx] = true; for(const pii &d : dir2) { pii nei = add(ci, d); pii bet = between(ci, nei); if(center[nei.fi][nei.se]) { if(done[center[nei.fi][nei.se]]) { res.adj_cnt++; res.adj_sum += val[bet.fi][bet.se]; res.min_leaf = min(res.min_leaf, val[bet.fi][bet.se]); } else { res.adj_cnt++; res.adj_sum += val[bet.fi][bet.se]; res.min_leaf = min(res.min_leaf, val[bet.fi][bet.se]); dfs_ret other_res = dfs(center[nei.fi][nei.se], idx); res.adj_sum += other_res.adj_sum; res.adj_cnt += other_res.adj_cnt; res.spec_cnt += other_res.spec_cnt; res.min_leaf = min(res.min_leaf, other_res.min_leaf); } } else { res.adj_cnt += 2; res.adj_sum += 2 * val[bet.fi][bet.se]; res.min_leaf = min(res.min_leaf, val[bet.fi][bet.se]); } } return res; } void solve() { // init cin >> n >> m; assi(int, val); assi(bool, filled); assi(int, center); for(int i = 0; i <= n; i++) { filled[i][0] = filled[i][m + 1] = true; } for(int j = 0; j <= m; j++) { filled[0][j] = filled[n + 1][j] = true; } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { cin >> val[i][j]; } } cin >> k; coords.assign(1 + k, mp(0, 0)); done.assign(1 + k, false); for(int i = 1; i <= k; i++) { pii &p = coords[i]; cin >> p.fi >> p.se; p.fi++; p.se++; ans += val[p.fi][p.se]; filled[p.fi][p.se] = true; center[p.fi][p.se] = i; } // try_extend everywhere for(int i = 1; i <= k; i++) { try_extend(i); } // diagonal pairs for(int i = 1; i <= k; i++) { if(done[i]) { continue; } const pii &ci = coords[i]; for(const pii &d1 : dirdia) { const pii &nei = add(ci, d1); // ? the neighbour might have been done already if(center[nei.fi][nei.se]) { vector<pii> empty_list = {{nei.fi, nei.se + d1.se}, {nei.fi + d1.fi, nei.se}}; for(const pii &d2 : dir4) { empty_list.pb(add(ci, d2)); } for(const pii &p : empty_list) { if(filled[p.fi][p.se]) { no(); } filled[p.fi][p.se] = true; ans += val[p.fi][p.se]; } done[center[nei.fi][nei.se]] = true; done[i] = true; } } } // try_extend everywhere for(int i = 1; i <= k; i++) { try_extend(i); } // short code for a subtask /* { for(int i = 1; i <= k; i++) { if(!done[i]) { const pii &ci = coords[i]; vector<int> tmp; for(const pii &d : dir4) { tmp.pb(val[ci.fi + d.fi][ci.se + d.se]); } sort(tmp.begin(), tmp.end()); ans += tmp[1] + tmp[2] + tmp[3]; } } } */ // dfs for(int i = 1; i <= k; i++) { if(done[i]) { continue; } dfs_ret res = dfs(i, -1); res.adj_cnt /= 2; res.adj_sum /= 2; res.spec_cnt *= 3; if(res.spec_cnt > res.adj_cnt) { no(); } if(res.spec_cnt == res.adj_cnt) { ans += res.adj_sum; } else { ans += res.adj_sum - res.min_leaf; } } answer(); } signed main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); solve(); return 0; } /* 5 5 1 5 1 5 1 5 1 5 1 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 3 3 1 3 3 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...