This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub tko919/library
#include "DataStructure/manhattanmst.hpp"
#pragma once #include "DataStructure/unionfind.hpp" template<typename T>pair<T,vector<pair<int,int>>> ManhattanMST(vector<T>& X,vector<T>& Y){ using Q=pair<T,pair<int,int>>; int n=X.size(); vector<int> ord(n); iota(ALL(ord),0); vector<Q> cand; rep(_,0,2){ rep(__,0,2){ sort(ALL(ord),[&](int i,int j){return X[i]+Y[i]<X[j]+Y[j];}); map<T,int> sweep; for(auto& i:ord){ for(auto it=sweep.lower_bound(-Y[i]);it!=sweep.end();it=sweep.erase(it)){ int j=it->second; if(X[i]-X[j]<Y[i]-Y[j])break; cand.push_back({abs(X[i]-X[j])+abs(Y[i]-Y[j]),{i,j}}); } sweep[-Y[i]]=i; } swap(X,Y); } for(auto& x:X)x=-x; } sort(ALL(cand)); UnionFind uni(n); T ret=0; vector<pair<int,int>> es; for(auto& [cost,uv]:cand){ auto [u,v]=uv; if(uni.unite(u,v)){ ret+=cost; es.push_back(uv); } } return {ret,es}; } /** * @brief Manhattan MST */
#line 2 "DataStructure/unionfind.hpp" struct UnionFind{ vector<int> par; int n; UnionFind(){} UnionFind(int _n):par(_n,-1),n(_n){} int root(int x){return par[x]<0?x:par[x]=root(par[x]);} bool same(int x,int y){return root(x)==root(y);} int size(int x){return -par[root(x)];} bool unite(int x,int y){ x=root(x),y=root(y); if(x==y)return false; if(size(x)>size(y))swap(x,y); par[y]+=par[x]; par[x]=y; n--; return true; } }; /** * @brief Union Find */ #line 3 "DataStructure/manhattanmst.hpp" template<typename T>pair<T,vector<pair<int,int>>> ManhattanMST(vector<T>& X,vector<T>& Y){ using Q=pair<T,pair<int,int>>; int n=X.size(); vector<int> ord(n); iota(ALL(ord),0); vector<Q> cand; rep(_,0,2){ rep(__,0,2){ sort(ALL(ord),[&](int i,int j){return X[i]+Y[i]<X[j]+Y[j];}); map<T,int> sweep; for(auto& i:ord){ for(auto it=sweep.lower_bound(-Y[i]);it!=sweep.end();it=sweep.erase(it)){ int j=it->second; if(X[i]-X[j]<Y[i]-Y[j])break; cand.push_back({abs(X[i]-X[j])+abs(Y[i]-Y[j]),{i,j}}); } sweep[-Y[i]]=i; } swap(X,Y); } for(auto& x:X)x=-x; } sort(ALL(cand)); UnionFind uni(n); T ret=0; vector<pair<int,int>> es; for(auto& [cost,uv]:cand){ auto [u,v]=uv; if(uni.unite(u,v)){ ret+=cost; es.push_back(uv); } } return {ret,es}; } /** * @brief Manhattan MST */