CF1537F Figure Fixing 题解

首先,不管大家的世界中有没有昼夜的概念,先祝大家早上中午晚上好!

这里是由星际和平公司赞助的mouse_boy的博客 , 今日带来的的是 CF1537F 题解

题目大意

  • 你有一个 \(n\) 点 ,\(m\) 条边的无相连通图

  • 你可以进行若干次操作 , 每次操作可以选择一条边 , 使祂连接的两个点权减去 \(k\) 加上 \(2k\)(简称 \(-+\))(逃

  • 问你若干次操作后能否使得每个点 \(v_i\) 权达到目标值 \(t_i\)

思路

  1. 可以将等式变形成为 \(v_i - t_i = 0\)
  2. 然后我们发现 \(\sum{v_i - t_i}\) 每次操作被减去了 \(2k\),最后等于 \(0\), 易得 ,\(\sum{v_i - t_i}\) 一定是偶数 , 否则不行
  3. 然后分类讨论 , 分为是二分图和不是二分图两种情况讨论
当这个图不是二分图时:
  我们发现,祂一定可以满足条件
当这个图是二分图时:
  我们对祂黑白染色,如果他两种颜色的权值和相等就可以,否则不行。
    证明:
      我们考虑到对于二分图的每一条都连接的两个点是不的颜色,所以只有权值和相等时才符合

代码(丑陋马蜂)


#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;
}
posted @ 2024-06-18 21:43  mouse_boy  阅读(26)  评论(0编辑  收藏  举报