牛客练习赛78:补题

牛客练习赛78:

B:CCA的搬运

注意数组的头和尾在实际模拟时的情形

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn],dp[maxn],n,m,x1,up[maxn],ans,sum,vis[maxn],d,b[maxn],k,t;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	    scanf("%d",&a[i]);
	for(int i=1;i<=m;i++){
		scanf("%d",&x1);
		if(x1!=b[k])b[++k]=x1;
	}
	for(int i=1;i<=k;i++){
		int x=b[i];
		if(!vis[x]){
			dp[++d]=x;
			ans+=sum;
			sum+=a[x];
			vis[x]=1;
		}
		else{
			int s=0,t=0;
			up[dp[d]]=a[x];
			for(int j=d;j>=1;j--){
				up[dp[j]]=up[dp[j+1]]+a[dp[j+1]];
				if(dp[j]==x){
					s=j;
					break;
				}
				t+=a[dp[j]];
			}
			for(int j=s;j<d;j++){
				dp[j]=dp[j+1];
			}
			dp[d]=x;
			ans+=t;
			up[x]=0;
			
		}
	}
	printf("%d\n",ans);
}

//29

C : CCA的子树
题意:
要选出两个节点,满足任意一个不是另一个的祖先节点,最大化以两个节点为根的子树的点权和 。
如果选不出两棵合法的子树,则输出“Error”。

思路:
从根节点1出发,我们可以找到左边子树的最大值与右边子树的最大值,二者一定可以保证不存在公共的祖先,并且满足了找左右最大值的要求,我们如果找到了这样的两棵子树那么就把他们更新一下答案。

并且在左右子树中也同样是这样的问题,我们依次往下即可求解正确的答案。

现在仅仅是把树形结构从二叉树变化成了多叉树,那么同样的道理就是在多个儿子中间找到最大的两个儿子,如果只有一个儿子就不能更新答案。并且返回包含节点在内的最大子树点。

这里判断只有单链一种情况,如果你把答案初始化到代表无穷小的话,可能会出现这样的数据把你卡掉,这道题目并没有考虑到。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll inf=-1e10;
const int maxn=5e6+5;
ll a[maxn],n,vis[maxn],ans=inf,to[maxn],head[maxn],nex[maxn],k;
void add(int x,int y){
	to[++k]=y;
	nex[k]=head[x];
	head[x]=k;
}
int dfs(int u,int f){
	int x=0,max1=0,max2=0;
	for(int i=head[u];i;i=nex[i]){
		int y=to[i];
		if(y==f)continue;
		int he=dfs(y,u);//找权值最大的子树节点号 
		a[u]+=a[y];//当前节点的所有子树权值和
		if(max1==0||a[max1]<a[he])max2=max1,max1=he;//更新最大子节点:先把最大子节点给次节点,再更新最大子节点 
		else if(max2==0||a[max2]<a[he])max2=he;//直接更新次大子节点 
	}
	if(max2!=0)//包含max1!=0,更新ans 
	ans=max(ans,a[max1]+a[max2]);//更新ans,最大子树权值+次大子树权值  
	if(max1==0||a[u]>a[max1])max1=u; // 当前树子树更新完毕后,继续向上传递,
	                                 //当前根节点变成子节点,可以被选用 
	return max1;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]); 
	}
	int x,y;
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	dfs(1,0);
	if(ans!=inf)printf("%lld\n",ans);
	else printf("Error\n");
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的数字调制就是把数字基带信号的频谱搬移到高频处,形成适合在信道中传输的带通信号基本的数字调制方式有振幅键控(ASK)、频移键控(FSK)、绝对相移键控(PSK)、相对(差分)相移键控(DPSK)在接收端可以基于想干解调或非相干解调还原数字基带信号+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值