arc205d - Non-Ancestor Matching

Problem

Problem Statement

You are given a rooted tree with N N N vertices numbered from 1 1 1 to N N N. Vertex 1 1 1 is the root, and the parent of vertex i i i ( 2 ≤ i ≤ N 2 \le i \le N 2≤i≤N) is vertex p i p_i pi ( 1 ≤ p i < i 1 \le p_i < i 1≤pi<i). Initially, all vertices are colored white.

You can perform the following sequence of operations zero or more times.

  • Choose a pair of integers ( u , v ) (u, v) (u,v) that satisfies all of the following conditions.

    • 1 ≤ u < v ≤ N 1 \le u < v \le N 1≤u<v≤N
    • Both vertices u u u and v v v are colored white.
    • u u u is not an ancestor of v v v.
  • Color vertices u u u and v v v black.

Here, " u u u is not an ancestor of v v v" means that you cannot reach vertex u u u from vertex v v v no matter how many times you perform the operation of moving to the parent of the current vertex.

Find the maximum number of operations you can perform when you perform operations in an appropriate order.

You are given T T T test cases, so find the answer for each of them.

Constraints

  • 1 ≤ T ≤ 5 × 10 4 1 \le T \le 5 \times 10^4 1≤T≤5×104
  • 2 ≤ N ≤ 5 × 10 5 2 \le N \le 5 \times 10^5 2≤N≤5×105
  • 1 ≤ p i < i 1 \le p_i < i 1≤pi<i
  • The sum of N N N over all test cases is at most 5 × 10 5 5 \times 10^5 5×105.
  • All input values are integers.

Translation

题目描述

给你一棵拥有 N N N 个节点的有根树,节点编号为 1 1 1 到 N N N。节点 1 1 1 是根节点,节点 i i i ( 2 ≤ i ≤ N 2 \le i \le N 2≤i≤N) 的父节点是 p i p_i pi ( 1 ≤ p i < i 1 \le p_i < i 1≤pi<i)。最初,所有节点都被染成白色。

你可以执行以下序列的操作零次或多次:

  • 选择一对整数 ( u , v ) (u, v) (u,v),并满足以下所有条件:

    • 1 ≤ u < v ≤ N 1 \le u < v \le N 1≤u<v≤N
    • 节点 u u u 和 v v v 均为白色。
    • u u u 不是 v v v 的祖先。
  • 将节点 u u u 和 v v v 染成黑色。

这里," u u u 不是 v v v 的祖先"意味着无论你执行多少次移动到当前节点父节点的操作,都无法从节点 v v v 到达节点 u u u。

请找到在以适当顺序执行操作时,你最多可以执行的操作次数。

给定 T T T 组测试用例,请为每组用例找到答案。

限制条件

  • 1 ≤ T ≤ 5 × 10 4 1 \le T \le 5 \times 10^4 1≤T≤5×104
  • 2 ≤ N ≤ 5 × 10 5 2 \le N \le 5 \times 10^5 2≤N≤5×105
  • 1 ≤ p i < i 1 \le p_i < i 1≤pi<i
  • 所有测试用例中 N N N 的总和不超过 5 × 10 5 5 \times 10^5 5×105。
  • 所有输入值均为整数。

Solutions

Approach 1

贪心。

先从最简单的情况考虑 ------ 考虑根节点和其子树,什么时候能够完全选干净子树 (当然,根节点本身选不了,如果子节点数量是奇数会有一个选不了)。

显然,当最大的子树 (即重儿子) 不大于其余所有子树和的时候。否则,假设大于,来继续递归考虑。

对于重儿子和其子树,其能够选干净的限制就是其重子树不大于其余所有子树和额外加上上一层传递来的其他所有子树和

于是如此递归。

Code
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

std::mt19937 rng(std::random_device{}());
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;

const int mod = 998244353;
const double ept = 1e-9;

void err() { cerr << endl; } template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cerr << arg << " "; err(args...); }
#define db(x...) { do { cerr << #x << " -> "; err(x); } while (0); }
#define dbv(vec) { cout << #vec << ": "; for(auto &v: vec) { cout << v << ' '; } cout << endl; }


int n;
int p[500500];
int s_cnt[500500];
int hv[500500];
int ans;

void dfs(int u, int f, int s) {
  db(u, hv[u])
  if(s > 0) --s, ++ans;

  int r = s_cnt[u] - s_cnt[hv[u]] - 1;
  if(s_cnt[hv[u]] <= r + s) {
    ans += (s_cnt[u] - 1 + s) / 2;
    return;
  }
  else if(hv[u] != 0) dfs(hv[u], u, s+r);
}

void solve(int T) {
  cin >> n;

  ans = 0;
  for(int i=1; i<=n; i++) s_cnt[i] = 1, hv[i] = 0;

  for(int i=2; i<=n; i++) cin >> p[i];

  for(int i=n; i>=2; i--) {
    s_cnt[p[i]] += s_cnt[i];
    if(s_cnt[hv[p[i]]] < s_cnt[i]) hv[p[i]] = i;
  }

  dfs(1, 1, 0);

  cout << ans << endl;
}

void init() {}

signed main() {
    //freopen("1.in", "r", stdin);
    //freopen("1.out", "w", stdout);
    //cout.flags(ios::fixed); cout.precision(8);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    init();
    int T_=1;
    std::cin >> T_;
    for(int _T=1; _T<=T_; _T++) { solve(_T); }
    return 0;
}
相关推荐
小欣加油13 分钟前
leetcode287寻找重复数
数据结构·c++·算法·leetcode
尽兴-43 分钟前
2.1 向量基础:Embedding、余弦相似度、欧氏距离、向量检索
算法·embedding·欧氏距离·向量检索·余弦相似度
Black蜡笔小新1 小时前
自动化AI算法训练服务器DLTM训推一体工作站赋能多行业智能化升级
人工智能·算法·自动化
怪兽学LLM1 小时前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪2 小时前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法
CC数学建模2 小时前
2026年江西省研究生数学建模竞赛1题:空间数据分析中的过拟合识别完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模
leo__5202 小时前
MATLAB实现牧羊人算法
开发语言·算法·matlab
Gauss松鼠会2 小时前
【GaussDB】GaussDB SMP特性调优详解
java·服务器·前端·数据库·sql·算法·gaussdb
Tisfy2 小时前
LeetCode 3689.最大子数组总值 I:What The Medium
算法·leetcode·题解·贪心·模拟·脑筋急转弯
葬送的代码人生2 小时前
JavaScript 数组完全指南:从入门到实战
前端·javascript·算法