Submission #439484

#TimeUsernameProblemLanguageResultExecution timeMemory
439484qwerasdfzxclFountain Parks (IOI21_parks)C++17
100 / 100
1042 ms146924 KiB
#include "parks.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; struct point{ int x, y, n; point(){} point(int _x, int _y, int _n): x(_x), y(_y), n(_n) {} bool operator<(const point &P) const{ if (x+y==P.x+P.y) return y<P.y; return x+y<P.x+P.y; } }; struct DSU{ int path[200200]; void init(int n){ for (int i=0;i<n;i++) path[i] = i; } int find(int s){ if (s==path[s]) return s; return path[s] = find(path[s]); } void merge(int s, int v){ int x = find(s), y = find(v); if (x==y) return; path[x] = y; } }dsu; struct Vertex{ int s, e, x, y; Vertex(){} Vertex(int _s, int _e, int _x, int _y): s(_s), e(_e), x(_x), y(_y) {} }; map<int, int> mp[200200]; multimap<pair<int, int>, int> INV; vector<Vertex> graph; vector<int> adj[400400], inv[400400]; bool make_edge(int x, int y, int x2, int y2){ if (mp[x].find(y)==mp[x].end() || mp[x2].find(y2)==mp[x2].end()) return 0; int tmp1 = mp[x][y], tmp2 = mp[x2][y2]; if (dsu.find(tmp1)==dsu.find(tmp2)) return 0; if (tmp1>tmp2) swap(tmp1, tmp2); dsu.merge(tmp1, tmp2); if (x==x2){ graph.emplace_back(tmp1, tmp2, x-1, (y+y2)/2); graph.emplace_back(tmp1, tmp2, x+1, (y+y2)/2); INV.insert(make_pair(make_pair(x-1, (y+y2)/2), (int)graph.size()-2)); INV.insert(make_pair(make_pair(x+1, (y+y2)/2), (int)graph.size()-1)); } else{ graph.emplace_back(tmp1, tmp2, (x+x2)/2, y-1); graph.emplace_back(tmp1, tmp2, (x+x2)/2, y+1); INV.insert(make_pair(make_pair((x+x2)/2, y-1), (int)graph.size()-2)); INV.insert(make_pair(make_pair((x+x2)/2, y+1), (int)graph.size()-1)); } return 1; } bool valid(int n){ bool ret = 1; for (int i=0;i<n-1;i++) if (dsu.find(i)!=dsu.find(i+1)) ret = 0; return ret; } int sccnum[400400], col[400400], cnt = 0; bool visited[400400]; stack<int> st; vector<vector<int>> scc; void dfs1(int s){ visited[s] = 1; for (auto &v:adj[s]) if (!visited[v]) dfs1(v); st.push(s); } void dfs2(int s){ visited[s] = 1; sccnum[s] = cnt; scc.back().push_back(s); for (auto &v:inv[s]) if (!visited[v]) dfs2(v); } void getscc(int n){ for (int i=0;i<n;i++){ for (auto &v:adj[i]) inv[v].push_back(i); } for (int i=0;i<n;i++) if (!visited[i]) dfs1(i); fill(visited, visited+n, 0); scc.push_back(vector<int>()); while(!st.empty()){ int cur = st.top(); st.pop(); if (visited[cur]) continue; cnt++; scc.push_back(vector<int>()); dfs2(cur); } } bool cmp(point &x, point &y){ if (x.y==y.y) return x.x<y.x; return x.y<y.y; } int construct_roads(std::vector<int> x, std::vector<int> y) { if (x.size() == 1) { build({}, {}, {}, {}); return 1; } std::vector<int> ansu, ansv, ansa, ansb; vector<point> vec; int n = x.size(); for (int i=0;i<n;i++){ vec.emplace_back(x[i], y[i], i); mp[x[i]][y[i]] = i; } ///graph modeling dsu.init(n); sort(vec.begin(), vec.end()); for (int i=0;i<n;i++) if ((vec[i].x+vec[i].y)%4==2){ make_edge(vec[i].x, vec[i].y, vec[i].x+2, vec[i].y); make_edge(vec[i].x, vec[i].y, vec[i].x, vec[i].y+2); } for (int i=0;i<n;i++) if ((vec[i].x+vec[i].y)%4==0){ make_edge(vec[i].x, vec[i].y, vec[i].x+2, vec[i].y); make_edge(vec[i].x, vec[i].y, vec[i].x, vec[i].y+2); } if (!valid(n)) return 0; for (auto iter=INV.begin();iter!=INV.end();++iter){ auto tmp = INV.equal_range(iter->first); auto iter1 = tmp.first, iter2 = tmp.second; for(;iter1!=iter2;++iter1){ if (iter1==iter) continue; adj[iter->second].push_back((iter1->second)^1); } } /// getscc((int)graph.size()); for (int i=0;i<(int)graph.size();i++) if (sccnum[i]==sccnum[i^1]) return 0; ///finding solution fill(col, col+(int)graph.size(), -1); for (auto &V:scc){ int tmp = 0; for (auto &x:V) if (col[x]==1) tmp = 1; for (auto &x:V) col[x] = tmp, col[x^1] = tmp^1; } /// for (int i=0;i<(int)graph.size();i++) if (col[i]==1){ ansu.push_back(graph[i].s); ansv.push_back(graph[i].e); ansa.push_back(graph[i].x); ansb.push_back(graph[i].y); } build(ansu, ansv, ansa, ansb); return 1; }
#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...