Submission #435968

#TimeUsernameProblemLanguageResultExecution timeMemory
43596879brue분수 공원 (IOI21_parks)C++17
35 / 100
1693 ms96940 KiB
#include <bits/stdc++.h> #include "parks.h" using namespace std; typedef long long ll; struct Point{ int x, y, idx; Point(){} Point(int x, int y, int idx): x(x), y(y), idx(idx){} bool operator<(const Point &r)const{ if(x==r.x) return x<r.x; return y<r.y; } }; struct Edge{ int u, v, idx; Edge(){} Edge(int u, int v, int idx): u(u), v(v), idx(idx){} bool operator==(const Edge &r)const{ return idx==r.idx; } }; struct dat{ int x, y; vector<Edge> vec; dat(){} dat(int x, int y, vector<Edge> vec): x(x), y(y), vec(vec){} bool operator<(const dat &r)const{ if(vec.size() != r.vec.size()) return vec.size() < r.vec.size(); return make_pair(x, y) < make_pair(r.x, r.y); } }; int xx[]={1, -1, 0, 0}, yy[]={0, 0, 1, -1}; int n; Point arr[200002]; map<pair<int, int>, int> idx; int par[200002]; int edgeU[400002], edgeV[400002], edgeCnt; int edgeA[400002], edgeB[400002]; int find(int x){ if(x==par[x]) return x; return par[x] = find(par[x]); } void merge(int x, int y){ x = find(x), y = find(y); par[y] = x; } set<pair<int, int> > criticalPoints; map<pair<int, int>, vector<pair<int, int> > > link; int findPoint(int x, int y){ if(idx.find(make_pair(x, y)) == idx.end()) return -1; return idx[make_pair(x, y)]; } bool findCritical(int x, int y){ return criticalPoints.find(make_pair(x, y)) != criticalPoints.end(); } set<pair<pair<int, int>, pair<int, int> > > avoid; int mid(int x, int y){ return (x+y)/2; } map<pair<int, int>, bool> visited; void dfs(pair<int, int> p){ int x = p.first, y = p.second; visited[p] = 1; for(auto nxt: link[p]){ if(visited[nxt]) continue; if(x){ if(x == nxt.first) avoid.insert(make_pair(make_pair(x-1, mid(y, nxt.second)), make_pair(x+1, mid(y, nxt.second)))); else avoid.insert(make_pair(make_pair(mid(x, nxt.first), y-1), make_pair(mid(x, nxt.first), y+1))); } dfs(nxt); } } bool firstTime; int construct_roads(vector<int> x, vector<int> y) { n = (int)x.size(); for(int i=0; i<n; i++){ arr[i] = Point(x[i], y[i], i); par[i] = i; idx[make_pair(x[i], y[i])] = i; } for(int i=0; i<n; i++){ if(findPoint(arr[i].x+2, arr[i].y) != -1){ edgeU[edgeCnt] = i, edgeV[edgeCnt] = idx[make_pair(arr[i].x+2, arr[i].y)]; edgeA[edgeCnt] = arr[i].x+1; edgeB[edgeCnt] = (arr[i].x+arr[i].y) % 4 == 0 ? arr[i].y-1 : arr[i].y+1; edgeCnt++; } if(findPoint(arr[i].x, arr[i].y+2) != -1){ edgeU[edgeCnt] = i, edgeV[edgeCnt] = idx[make_pair(arr[i].x, arr[i].y+2)]; edgeA[edgeCnt] = (arr[i].x+arr[i].y) % 4 == 0 ? arr[i].x+1 : arr[i].x-1; edgeB[edgeCnt] = arr[i].y+1; edgeCnt++; } } for(int i=0; i<edgeCnt; i++) merge(edgeU[i], edgeV[i]); for(int i=0; i<n; i++) if(find(0) != find(i)) return 0; for(int i=0; i<n; i++){ if(findPoint(arr[i].x, arr[i].y+2) == -1 || findPoint(arr[i].x+2, arr[i].y) == -1 || findPoint(arr[i].x+2, arr[i].y+2) == -1) continue; criticalPoints.insert(make_pair(arr[i].x+1, arr[i].y+1)); } pair<int, int> origin (0, 0); for(auto p: criticalPoints){ if((p.first+p.second)%4 == 2){ if(findCritical(p.first, p.second + 2)) link[p].push_back(make_pair(p.first, p.second+2)); if(findCritical(p.first, p.second - 2)) link[p].push_back(make_pair(p.first, p.second-2)); if(!findCritical(p.first-2, p.second)){ link[origin].push_back(make_pair(p.first-2, p.second)); link[make_pair(p.first-2, p.second)].push_back(p); } if(!findCritical(p.first+2, p.second)){ link[origin].push_back(make_pair(p.first+2, p.second)); link[make_pair(p.first+2, p.second)].push_back(p); } } else{ if(findCritical(p.first + 2, p.second)) link[p].push_back(make_pair(p.first+2, p.second)); if(findCritical(p.first - 2, p.second)) link[p].push_back(make_pair(p.first-2, p.second)); if(!findCritical(p.first, p.second-2)){ link[origin].push_back(make_pair(p.first, p.second-2)); link[make_pair(p.first, p.second-2)].push_back(p); } if(!findCritical(p.first, p.second+2)){ link[origin].push_back(make_pair(p.first, p.second+2)); link[make_pair(p.first, p.second+2)].push_back(p); } } } dfs(origin); int pnt = 0; for(int i=0; i<edgeCnt; i++){ auto minPoint = make_pair(min(arr[edgeU[i]].x, arr[edgeV[i]].x), min(arr[edgeU[i]].y, arr[edgeV[i]].y)); auto maxPoint = make_pair(max(arr[edgeU[i]].x, arr[edgeV[i]].x), max(arr[edgeU[i]].y, arr[edgeV[i]].y)); if(avoid.find(make_pair(minPoint, maxPoint)) != avoid.end()) continue; swap(edgeU[i], edgeU[pnt]); swap(edgeV[i], edgeV[pnt]); swap(edgeA[i], edgeA[pnt]); swap(edgeB[i], edgeB[pnt]); pnt++; } edgeCnt = pnt; assert(pnt >= n-1); build(vector<int>(edgeU, edgeU+n-1), vector<int>(edgeV, edgeV+n-1), vector<int>(edgeA, edgeA+n-1), vector<int>(edgeB, edgeB+n-1)); 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...