#include #include #include #include #include #include #include class Site { public: int posX; int posY; Site* groupID; Site* oppGroup; }; std::vector sites; int distance(Site& s1, Site& s2) { return std::abs(s1.posX - s2.posX) + std::abs(s1.posY - s2.posY); } Site* find(Site* s) { if(s == nullptr) return nullptr; if(s->groupID == s) return s; Site* res = find(s->groupID); s->groupID = res; return res; } void doUnion(Site* s1, Site* s2) { find(s1)->groupID = find(s2); } bool setOpposite(Site* sFrom, Site* sTo) { if(sFrom->oppGroup == nullptr) { sFrom->oppGroup = sTo; } else { Site* oppElem = find(sFrom->oppGroup); doUnion(oppElem, sTo); return find(sTo) != find(sTo->oppGroup); } return true; } void solve(std::istream& in) { int nSites; in >> nSites; // Read in sites sites.resize(nSites); for(int i = 0; i < nSites; i++) { in >> sites[i].posX; in >> sites[i].posY; sites[i].groupID = &sites[i]; sites[i].oppGroup = nullptr; } // Add all n^2 edges std::vector> edges; for(int i = 0; i < nSites; i++) { for(int j = i+1; j < nSites; j++) { int dist = distance(sites[i], sites[j]); edges.emplace_back(-dist, &sites[i], &sites[j]); } } std::sort(edges.begin(), edges.end()); // Put in opposite groups until we can't any omre int biggestDist = 0; for(auto e : edges) { Site* s1 = std::get<1>(e); Site* s2 = std::get<2>(e); bool couldSetOpposite = setOpposite(s1, s2) && setOpposite(s2, s1); if(!couldSetOpposite) { biggestDist = -std::get<0>(e); break; } } std::cout << biggestDist << std::endl; } int main(int argc, char** argv) { if (argc > 1) { std::ifstream in (argv[1]); solve (in); } else { solve(std::cin); } return 0; }