#Z2322. 买保险

一.题目

二.思路

1.暴力

训练的时候,初看这道题,这不就打个暴力吗?

2.暴力代码

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,fa,x,y,vis[1000001],ans;
vector<int> vec[1000001];
void dfs(int x,int y)
{
	if(y == -1) return ;
	vis[x] = 1;
 for(int i = 0;i < vec[x].size();i++) dfs(vec[x][i],y - 1);
}
signed main()
{
  cin>>n>>m;
  for(int i = 2;i <= n;i++)
  {
    cin>>fa;
	vec[fa].push_back(i);
  }
  while(m--)
  {
    cin>>x>>y;
	dfs(x,y);
  }
  for(int i = 1;i <= n;i++)
	    if(vis[i])
			ans++;
  cout<<ans;
  return 0;
}

结果。。。

3.正解

赛后仔细研究了一下,其实也不难,只要借鉴一下线段树lazy标记的思想,打个标记,dfs的时候下传就行了。细节有点多,可以看看代码。

4.代码

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,fa,x,y,vis[1000001],ans,t[1000001];
vector<int> vec[1000001];
void dfs(int x,int fa,int y)
{
  t[x] = max(t[x],y);//因为有可能父节点下传了保险,自己也买了一份保险
	if(t[x]) vis[x] = 1;
 for(int i = 0;i < vec[x].size();i++)
   if(fa != vec[x][i])
   {
     if(t[x] - 1 >= 0) dfs(vec[x][i],x,t[x] - 1);
     else dfs(vec[x][i],x,0);
   }
}
signed main()
{
  cin>>n>>m;
  for(int i = 2;i <= n;i++)
  {
    cin>>fa;
	vec[fa].push_back(i);
	vec[i].push_back(fa);
  }
  while(m--)
  {
    cin>>x>>y;
    y++;
    t[x] = max(t[x],y);//因为一个人有可能买多份保险,所以要取其中往后最多的子孙的那一份
  }
  dfs(1,0,0);
  for(int i = 1;i <= n;i++)
	    if(vis[i])
			ans++;
  cout<<ans;
  return 0;
}

三.结语

如果这篇博客对您有帮助的话,请点个赞支持一下吖!( •̀ ω •́ )✧

相关推荐
2401_8914821735 分钟前
多平台UI框架C++开发
开发语言·c++·算法
88号技师1 小时前
2026年3月中科院一区SCI-贝塞尔曲线优化算法Bezier curve-based optimization-附Matlab免费代码
开发语言·算法·matlab·优化算法
t198751281 小时前
三维点云最小二乘拟合MATLAB程序
开发语言·算法·matlab
无敌昊哥战神1 小时前
【LeetCode 257】二叉树的所有路径(回溯法/深度优先遍历)- Python/C/C++详细题解
c语言·c++·python·leetcode·深度优先
x_xbx2 小时前
LeetCode:148. 排序链表
算法·leetcode·链表
Darkwanderor2 小时前
三分算法的简单应用
c++·算法·三分法·三分算法
2401_831920742 小时前
分布式系统安全通信
开发语言·c++·算法
WolfGang0073212 小时前
代码随想录算法训练营 Day17 | 二叉树 part07
算法
温九味闻醉2 小时前
关于腾讯广告算法大赛2025项目分析1 - dataset.py
人工智能·算法·机器学习
炽烈小老头2 小时前
【 每天学习一点算法 2026/03/23】数组中的第K个最大元素
学习·算法·排序算法