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:
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 1≤n≤1000) — 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 −109≤xi,yi≤109), and r i r_i ri ( 1 ≤ r i ≤ 1 0 9 1 \leq r_i \leq 10^9 1≤ri≤109) — 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.
对于已经相切的两个圆,想要在调整其一个半径后还能相切,那么两个圆半径变化的大小一定是一样的,即其中一个圆半径变化 Δ r Δr Δr ,另一个圆半径一定会变化变化 − Δ r −Δr −Δr 。如果用图来描述,则可以将每个圆视为一个节点,则只要两个节点之间存在一条路径,则其中任何一个点的半径变化已知,则另一个点的半径变化已知。
我们只需要判断增加和减少的圆圈个数不相等即可,在判断过程中,可以用二染色法来判断是否有两个原本已经相切的圆变化趋势相同(即同时变大/变小)
此解法时间复杂度为 O ( n 2 ) \mathcal O(n ^ 2) O(n2)
#include
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;
}