#include #include #include #include #include using namespace std; struct hashFunction { size_t operator()(const tuple& x) const { return get<0>(x) ^ get<1>(x) ^ get<2>(x) ^ get<3>(x); } }; int main() { int n; cin >> n; // Double the centre coordinates, so diameter becomes radius vector> models(n); for(int i = 0; i < n; ++i) { int x, y, d; cin >> x >> y >> d; models[i] = make_tuple(2 * x, 2 * y, d); } int D = get<2>(*max_element(models.begin(), models.end(), [](const auto& a, const auto& b) { return get<2>(a) < get<2>(b); })) + 102; unordered_map, hashFunction>>> sparse_grid; for(int i = 0; i < n; ++i) { auto [x, y, d] = models[i]; for(int dx : {-d, d}) { for(int dy : {-d, d}) { sparse_grid[(x + dx) / D][(y + dy) / D].insert(make_tuple(i, x, y, d)); } } } vector> graph; for(int i = 0; i < n; ++i) { auto [x, y, r] = models[i]; int xd = x / D, yd = y / D; unordered_set, hashFunction> other_models; for(int xdd = (x - r - 102) / D; xdd <= (x + r + 102) / D; ++xdd) { for(int ydd = (y - r - 102) / D; ydd <= (y + r + 102) / D; ++ydd) { for(const auto& model : sparse_grid[xdd][ydd]) { auto [j, xx, yy, rr] = model; if(i != j) { other_models.insert(model); } } } } vector neighs; for(const auto& model : other_models) { auto [j, xx, yy, rr] = model; if((x - xx) * (x - xx) + (y - yy) * (y - yy) <= (r + rr + 101) * (r + rr + 101)) { neighs.push_back(j); } } if(neighs.size() < 1 + (n >= 7)) { cout << "no" << endl; return 0; } graph.push_back(neighs); } vector stack = {0}; vector visited(n, false); visited[0] = true; while(!stack.empty()) { int curr = stack.back(); stack.pop_back(); for(int neigh : graph[curr]) { if(!visited[neigh]) { visited[neigh] = true; stack.push_back(neigh); } } } cout << (count(visited.begin(), visited.end(), true) == n ? "yes" : "no") << endl; return 0; }