European Championship 2024 I. Disks

Disks

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

You are given n n n disks in the plane. The center of each disk has integer coordinates, and the radius of each disk is a positive integer. No two disks overlap in a region of positive area, but it is possible for disks to be tangent to each other.

Your task is to determine whether it is possible to change the radii of the disks in such a way that:

  • Disks that were tangent to each other remain tangent to each other.
  • No two disks overlap in a region of positive area.
  • The sum of all radii strictly decreases.

The new radii are allowed to be arbitrary positive real numbers. The centers of the disks cannot be changed.

Input

The first line contains an integer n n n ( 1 ≤ n ≤ 1000 1\le n \le 1000 1n1000) — the number of disks.

The next n n n lines contain three integers each. The i i i-th of such lines contains x i x_i xi, y i y_i yi ( − 1 0 9 ≤ x i , y i ≤ 1 0 9 -10^9 \leq x_i, y_i \leq 10^9 109xi,yi109), and r i r_i ri ( 1 ≤ r i ≤ 1 0 9 1 \leq r_i \leq 10^9 1ri109) — the coordinates of the center, and the radius, of the i i i-th disk.

Output

Print YES \texttt{YES} YES if it is possible to change the radii in the desired manner. Otherwise, print NO \texttt{NO} NO.

Example

i n p u t \tt input input
5
0 2 1
0 0 1
4 -3 4
11 0 3
11 5 2
o u t p u t \tt output output
YES
i n p u t \tt input input
4
2 2 2
7 2 3
7 7 2
2 7 3
o u t p u t \tt output output
NO

Note

In the first sample, one can decrease the radii of the first and third disk by 0.5 0.5 0.5, and increase the radius of the second disk by 0.5 0.5 0.5. This way, the sum of all radii decreases by 0.5 0.5 0.5. The situation before and after changing the radii is depicted below.

First sample (left) and a valid way to change the radii of the disks (right).

In the second sample, depicted below, there is no way to change the radii of the disks in the desired manner.

Second sample.

Tutorial

对于已经相切的两个圆,想要在调整其一个半径后还能相切,那么两个圆半径变化的大小一定是一样的,即其中一个圆半径变化 Δ r Δr Δr ,另一个圆半径一定会变化变化 − Δ r −Δr Δr 。如果用图来描述,则可以将每个圆视为一个节点,则只要两个节点之间存在一条路径,则其中任何一个点的半径变化已知,则另一个点的半径变化已知。

我们只需要判断增加和减少的圆圈个数不相等即可,在判断过程中,可以用二染色法来判断是否有两个原本已经相切的圆变化趋势相同(即同时变大/变小)

此解法时间复杂度为 O ( n 2 ) \mathcal O(n ^ 2) O(n2)

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long

signed main() {
    int n;
    cin >> n;
    vector<array<int, 3>> a(n);
    vector<int> g[n], color(n, -1);
    for (array<int, 3> &ai : a) {
        cin >> ai[0] >> ai[1] >> ai[2];
    }
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if (pow(a[i][0] - a[j][0], 2) + pow(a[i][1] - a[j][1], 2) == pow(a[i][2] + a[j][2], 2)) {
                g[i].emplace_back(j);
                g[j].emplace_back(i);
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        if (color[i] == -1) {
            color[i] = 0;
            int cnt = 0;
            bool ok = true;
            queue<int> q;
            q.emplace(i);
            while (q.size()) {
                int u = q.front();
                q.pop();
                cnt += (color[u] ? -1 : 1);
                for (int v : g[u]) {
                    if (color[u] == color[v]) {
                        ok = false;
                    } else if (color[v] == -1) {
                        color[v] = color[u] ^ 1;
                        q.emplace(v);
                    }
                }
            }
            if (ok and cnt) {
                cout << "YES";
                return;
            }
        }
    }
    cout << "NO";
    return 0;
}
  • 31
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值