CodeForces-1339 D. Edge Weight Assignment Conclusion + Dyeing

CodeForces - 1339 D. Edge Weight Assignment

Original title address:

http://codeforces.com/contest/1339/problem/D

Basic questions:

You need to fill in a number for each edge of a tree, so that the xor of the simple path between each leaf node is zero, and you need to find the maximum number of different numbers used for the construction that meets this condition. And minimum.

The basic idea:

Find the minimum value first: By observing the sample, you can find that if the path between each leaf node is even, then we can definitely use a number to complete the construction, then the minimum value is 1, otherwise we can try The minimum value was found to be 3.
So how to judge whether the path between each leaf node is even, we can color the tree black and white. If the color of the leaf node is the same, then it means that the two paths are even.
Then find the maximum value: for the maximum value, as long as the node directly connected to multiple leaf nodes is determined, the same number must be used to go to the edge of those leaf nodes, so we first define the answer as n-1 And then subtract the number of edges in the same color in the above case.

Reference Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false)
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)
#define INF 0x3f3f3f3f

inline int read() {
  int x = 0, neg = 1; char op = getchar();
  while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
  while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
  return neg * x;
}
inline void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}
const int maxn = 1e5 + 10;
vector<int> G[maxn];
int n,c[maxn],du[maxn];
void dfs(int u,int f) {
  c[u] = f;
  for (int i = 0; i < G[u].size(); i++) {
    int to = G[u][i];
    if (c[to] != 0) continue;
    dfs(to, 3 - f);
  }
}
signed main() {
  IO;
  n = read();
  rep(i, 1, n - 1) {
    int u, v;
    u = read(), v = read();
    G[u].push_back(v);
    G[v].push_back(u);
    du[u]++;
    du[v]++;
  }
  rep(i, 1, n) {
    if (du[i] == 1) {
      c[G[i][0]]++;
    }
  }
  int ans = n - 1;
  rep(i, 1, n) {
    ans -= max(0LL, c[i] - 1);
  }
  mset(c, 0);
  dfs(1, 1);
  int f1 = 0, f2 = 0;
  rep(i, 1, n) {
    if (du[i] == 1) {
      if (c[i] == 1) f1 = 1;
      else if (c[i] == 2) f2 = 1;
    }
  }
  int mi = 0;
  if (f1 + f2 < 2) mi = 1;
  else mi = 3;
  cout << mi << " " << ans << '\n';
  return 0;
}
Published 23 original articles · won 7 · visited 1736

Guess you like

Origin blog.csdn.net/weixin_44164153/article/details/105511081