This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "parks.h"
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
struct DSU{
int par[N], setsize[N], setcnt;
void reset(int n){
for(int i = 0; i < n; i++) par[i] = i, setsize[i] = 1;
setcnt = n;
}
int setfind(int a){
if(a == par[a]) return a;
else return par[a] = setfind(par[a]);
}
void setunion(int a, int b){
a = setfind(a), b = setfind(b);
if(a != b){
if(setsize[b] > setsize[a]) swap(a, b);
par[b] = par[a];
setsize[a] += setsize[b];
setcnt--;
}
}
};
DSU dsu;
struct Point{
int x, y;
bool operator < (const Point &sc) const{
if(y == sc.y) return x < sc.x;
else return y < sc.y;
}
};
map<Point, int> nodes;
map<Point, Point> edges;
map<Point, bool> vis;
bool check(Point p){
if(nodes.find({p.x - 1, p.y - 1}) != nodes.end() && nodes.find({p.x - 1, p.y + 1}) != nodes.end() && dsu.setfind(nodes[{p.x - 1, p.y - 1}]) != dsu.setfind(nodes[{p.x - 1, p.y + 1}])){
edges[{nodes[{p.x - 1, p.y - 1}], nodes[{p.x - 1, p.y + 1}]}] = p;
dsu.setunion(nodes[{p.x - 1, p.y - 1}], nodes[{p.x - 1, p.y + 1}]);
return true;
}
if(nodes.find({p.x - 1, p.y - 1}) != nodes.end() && nodes.find({p.x + 1, p.y - 1}) != nodes.end() && dsu.setfind(nodes[{p.x - 1, p.y - 1}]) != dsu.setfind(nodes[{p.x + 1, p.y - 1}])){
edges[{nodes[{p.x - 1, p.y - 1}], nodes[{p.x + 1, p.y - 1}]}] = p;
dsu.setunion(nodes[{p.x - 1, p.y - 1}], nodes[{p.x + 1, p.y - 1}]);
return true;
}
if(nodes.find({p.x + 1, p.y - 1}) != nodes.end() && nodes.find({p.x + 1, p.y + 1}) != nodes.end() && dsu.setfind(nodes[{p.x + 1, p.y - 1}]) != dsu.setfind(nodes[{p.x + 1, p.y + 1}])){
edges[{nodes[{p.x + 1, p.y - 1}], nodes[{p.x + 1, p.y + 1}]}] = p;
dsu.setunion(nodes[{p.x + 1, p.y - 1}], nodes[{p.x + 1, p.y + 1}]);
return true;
}
if(nodes.find({p.x + 1, p.y + 1}) != nodes.end() && nodes.find({p.x - 1, p.y + 1}) != nodes.end() && dsu.setfind(nodes[{p.x + 1, p.y + 1}]) != dsu.setfind(nodes[{p.x - 1, p.y + 1}])){
edges[{nodes[{p.x + 1, p.y + 1}], nodes[{p.x - 1, p.y + 1}]}] = p;
dsu.setunion(nodes[{p.x + 1, p.y + 1}], nodes[{p.x - 1, p.y + 1}]);
return true;
}
return false;
}
void dfs(Point p){
if(nodes.find({p.x - 1, p.y - 1}) != nodes.end() && nodes.find({p.x - 1, p.y + 1}) != nodes.end() && !vis[{p.x - 2, p.y}] && dsu.setfind(nodes[{p.x - 1, p.y - 1}]) != dsu.setfind(nodes[{p.x - 1, p.y + 1}])){
edges[{nodes[{p.x - 1, p.y - 1}], nodes[{p.x - 1, p.y + 1}]}] = {p.x - 2, p.y};
dsu.setunion(nodes[{p.x - 1, p.y - 1}], nodes[{p.x - 1, p.y + 1}]);
vis[{p.x - 2, p.y}] = true;
dfs({p.x - 2, p.y});
}
if(nodes.find({p.x - 1, p.y - 1}) != nodes.end() && nodes.find({p.x + 1, p.y - 1}) != nodes.end() && !vis[{p.x, p.y - 2}] && dsu.setfind(nodes[{p.x - 1, p.y - 1}]) != dsu.setfind(nodes[{p.x + 1, p.y - 1}])){
edges[{nodes[{p.x - 1, p.y - 1}], nodes[{p.x + 1, p.y - 1}]}] = {p.x, p.y - 2};
dsu.setunion(nodes[{p.x - 1, p.y - 1}], nodes[{p.x + 1, p.y - 1}]);
vis[{p.x, p.y - 2}] = true;
dfs({p.x, p.y - 2});
}
if(nodes.find({p.x + 1, p.y - 1}) != nodes.end() && nodes.find({p.x + 1, p.y + 1}) != nodes.end() && !vis[{p.x + 2, p.y}] && dsu.setfind(nodes[{p.x + 1, p.y - 1}]) != dsu.setfind(nodes[{p.x + 1, p.y + 1}])){
edges[{nodes[{p.x + 1, p.y - 1}], nodes[{p.x + 1, p.y + 1}]}] = {p.x + 2, p.y};
dsu.setunion(nodes[{p.x + 1, p.y - 1}], nodes[{p.x + 1, p.y + 1}]);
vis[{p.x + 2, p.y}] = true;
dfs({p.x + 2, p.y});
}
if(nodes.find({p.x + 1, p.y + 1}) != nodes.end() && nodes.find({p.x - 1, p.y + 1}) != nodes.end() && !vis[{p.x, p.y + 2}] && dsu.setfind(nodes[{p.x + 1, p.y + 1}]) != dsu.setfind(nodes[{p.x - 1, p.y + 1}])){
edges[{nodes[{p.x + 1, p.y + 1}], nodes[{p.x - 1, p.y + 1}]}] = {p.x, p.y + 2};
dsu.setunion(nodes[{p.x + 1, p.y + 1}], nodes[{p.x - 1, p.y + 1}]);
vis[{p.x, p.y + 2}] = true;
dfs({p.x, p.y + 2});
}
if(!vis[{p.x - 2, p.y}] && check({p.x - 2, p.y})){
vis[{p.x - 2, p.y}] = true;
dfs({p.x - 2, p.y});
}
if(!vis[{p.x + 2, p.y}] && check({p.x + 2, p.y})){
vis[{p.x + 2, p.y}] = true;
dfs({p.x + 2, p.y});
}
if(!vis[{p.x, p.y - 2}] && check({p.x, p.y - 2})){
vis[{p.x, p.y - 2}] = true;
dfs({p.x, p.y - 2});
}
if(!vis[{p.x, p.y + 2}] && check({p.x, p.y + 2})){
vis[{p.x, p.y + 2}] = true;
dfs({p.x, p.y + 2});
}
}
int construct_roads(vector<int> xvec, vector<int> yvec){
int n = xvec.size();
dsu.reset(n);
for(int i = 0; i < n; i++) nodes[{xvec[i], yvec[i]}] = i;
if(*max_element(xvec.begin(), xvec.end()) <= 2){ // subtask 1
for(auto p : nodes){
Point po = p.first;
if(nodes.find({2, po.y + 2}) != nodes.end()){
edges[{p.second, nodes[{2, po.y + 2}]}] = {1, po.y + 1};
dsu.setunion(p.second, nodes[{2, po.y + 2}]);
}
}
}
else if(*max_element(xvec.begin(), xvec.end()) <= 4){ // subtask 2
vector<int> x2, x4;
for(int i = 0; i < n; i++){
if(xvec[i] == 2) x2.push_back(yvec[i]);
else if(xvec[i] == 4) x4.push_back(yvec[i]);
}
sort(x2.begin(), x2.end());
sort(x4.begin(), x4.end());
for(auto y : x2){
if(nodes.find({2, y + 2}) != nodes.end()){
edges[{nodes[{2, y}], nodes[{2, y + 2}]}] = {1, y + 1};
dsu.setunion(nodes[{2, y}], nodes[{2, y + 2}]);
}
}
for(auto y : x4){
if(nodes.find({4, y + 2}) != nodes.end()){
edges[{nodes[{4, y}], nodes[{4, y + 2}]}] = {5, y + 1};
dsu.setunion(nodes[{4, y}], nodes[{4, y + 2}]);
}
if(nodes.find({2, y}) != nodes.end()){
edges[{nodes[{4, y}], nodes[{2, y}]}] = {3, y + 1};
dsu.setunion(nodes[{4, y}], nodes[{2, y}]);
}
}
}
else if(*max_element(xvec.begin(), xvec.end()) <= 6){ // subtask 3
vector<int> x2, x4, x6;
for(int i = 0; i < n; i++){
if(xvec[i] == 2) x2.push_back(yvec[i]);
else if(xvec[i] == 4) x4.push_back(yvec[i]);
else if(xvec[i] == 6) x6.push_back(yvec[i]);
}
sort(x2.begin(), x2.end());
sort(x4.begin(), x4.end());
sort(x6.begin(), x6.end());
for(auto y : x2){
if(nodes.find({2, y + 2}) != nodes.end()){
edges[{nodes[{2, y}], nodes[{2, y + 2}]}] = {1, y + 1};
dsu.setunion(nodes[{2, y}], nodes[{2, y + 2}]);
}
}
for(auto y : x6){
if(nodes.find({6, y + 2}) != nodes.end()){
edges[{nodes[{6, y}], nodes[{6, y + 2}]}] = {7, y + 1};
dsu.setunion(nodes[{6, y}], nodes[{6, y + 2}]);
}
}
for(auto y : x4){
if(nodes.find({4, y + 2}) != nodes.end()){
dsu.setunion(nodes[{4, y}], nodes[{4, y + 2}]);
}
}
for(auto y : x4){
if(nodes.find({6, y}) != nodes.end() && dsu.setfind(nodes[{4, y}]) != dsu.setfind(nodes[{6, y}])){
edges[{nodes[{4, y}], nodes[{6, y}]}] = {5, y - 1};
vis[{5, y - 1}] = true;
dsu.setunion(nodes[{4, y}], nodes[{6, y}]);
if(nodes.find({2, y}) != nodes.end() && dsu.setfind(nodes[{4, y}]) != dsu.setfind(nodes[{2, y}])){
edges[{nodes[{2, y}], nodes[{4, y}]}] = {3, y + 1};
vis[{3, y + 1}] = true;
dsu.setunion(nodes[{2, y}], nodes[{4, y}]);
}
}
else if(nodes.find({2, y}) != nodes.end() && dsu.setfind(nodes[{4, y}]) != dsu.setfind(nodes[{2, y}])){
edges[{nodes[{2, y}], nodes[{4, y}]}] = {3, y - 1};
vis[{3, y - 1}] = true;
dsu.setunion(nodes[{2, y}], nodes[{4, y}]);
}
}
for(auto y : x4){
if(nodes.find({4, y + 2}) != nodes.end()){
if(!vis[{3, y + 1}]){
edges[{nodes[{4, y}], nodes[{4, y + 2}]}] = {3, y + 1};
}
else if(!vis[{5, y + 1}]){
edges[{nodes[{4, y}], nodes[{4, y + 2}]}] = {5, y + 1};
}
// else assert(false);
}
}
}
else{ // subtask 4, 5
stack<Point> que;
Point fpo = nodes.begin()->first;
if(nodes.find({fpo.x + 2, fpo.y}) != nodes.end()){
dfs({fpo.x + 1, fpo.y - 1});
}
else if(nodes.find({fpo.x, fpo.y + 2}) != nodes.end()){
dfs({fpo.x - 1, fpo.y + 1});
}
}
if(dsu.setcnt == 1){
vector<int> vecs[4];
for(auto p : edges){
vecs[0].push_back(p.first.x);
vecs[1].push_back(p.first.y);
vecs[2].push_back(p.second.x);
vecs[3].push_back(p.second.y);
}
build(vecs[0], vecs[1], vecs[2], vecs[3]);
return 1;
}
else return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |