CF1537F Figure Fixing 题解
首先,不管大家的世界中有没有昼夜的概念,先祝大家早上中午晚上好!
这里是由星际和平公司赞助的mouse_boy的博客 , 今日带来的的是 CF1537F 题解
题目大意
-
你有一个 \(n\) 点 ,\(m\) 条边的无相连通图
-
你可以进行若干次操作 , 每次操作可以选择一条边 , 使祂连接的两个点权减去 \(k\) 加上 \(2k\)(简称 \(-+\))(逃
-
问你若干次操作后能否使得每个点 \(v_i\) 权达到目标值 \(t_i\)
思路
- 可以将等式变形成为 \(v_i - t_i = 0\)
- 然后我们发现 \(\sum{v_i - t_i}\) 每次操作被减去了 \(2k\),最后等于 \(0\), 易得 ,\(\sum{v_i - t_i}\) 一定是偶数 , 否则不行
- 然后分类讨论 , 分为是二分图和不是二分图两种情况讨论
当这个图不是二分图时:
我们发现,祂一定可以满足条件
当这个图是二分图时:
我们对祂黑白染色,如果他两种颜色的权值和相等就可以,否则不行。
证明:
我们考虑到对于二分图的每一条都连接的两个点是不的颜色,所以只有权值和相等时才符合
代码(丑陋马蜂)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int kMaxN = 2e5 + 5;
ll t, n, m, x, y, s, cnt, sum, co[kMaxN], u[kMaxN];
bool f;
vector<int> g[kMaxN];
void dfs(int x, int c) {
for (auto v : g[x]) {
if (!co[v]) {
co[v] = c, dfs(v, 3 - c);
} else {
if (co[v] != c) {
f = 1;
}
}
if (f) {
return;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
for (cin >> t; t; t--) {
for (int i = 1; i <= n; i++) {
g[i].clear(), co[i] = cnt = sum = 0;
}
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> u[i];
}
for (int i = 1; i <= n; i++) {
cin >> x, u[i] -= x, cnt += u[i];
}
for (int i = 1; i <= m; i++) {
cin >> x >> y;
g[x].push_back(y), g[y].push_back(x);
}
if (cnt & 1) {
cout << "NO\n";
continue;
}
f = cnt = 0;
dfs(1, 1);
for (int i = 1; i <= n; i++) {
(co[i] == 1 ? cnt : sum) += u[i];
}
cout << (f || cnt == sum ? "YES\n" : "NO\n");
}
return 0;
}