2025/2/15课堂记录

news/2025/2/22 21:48:27/文章来源:https://www.cnblogs.com/yongshao/p/18717425

目录

  1. 数字转换
  2. 皇宫看守

  • 数字转换

这是一道树的直径题。

首先,树的直径定义是:树上两个结点之间的最短(加权)路中最长的一条路径(和二分答案没关)

但由于贪心思想,这个路径一定起点终点是两片叶子结点

如图,这棵树的直径就是5,即节点3和节点4之间的最短路径

那么,求树的直径有啥方法?

方法一:找每个节点的最长链与次长链之和的最大值

这是代码
  //  树的直径 dp实现; 
//  https://blog.csdn.net/qq_42211531/article/details/86579115
//  dp[u][0]: 结点u的最长儿子链
//  dp[u][1]: 结点u的次长儿子链 
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 100005;
int head[MAX], dp[MAX][2];
int n, s, cnt, ans;struct EDGE
{int v, w, next;
}e[MAX];void Add(int u, int v, int w)
{e[++cnt].v = v;e[cnt].w = w;e[cnt].next = head[u];head[u] = cnt;
}//   利用孩子的最长链去更新父亲的最长链和次长链 
void DFS(int u, int fa)
{//dp[u][0]:最长子链; dp[u][1]:次长子链 dp[u][0] = dp[u][1] = 0;for(int i = head[u]; i ; i = e[i].next){int v = e[i].v;int w = e[i].w;if(v != fa){DFS(v, u);if(dp[u][0] < dp[v][0] + w)   //    父亲u的最长 < 孩子v的最长 + (u,v)边长 {dp[u][1]= dp[u][0];dp[u][0] = dp[v][0] + w;}else if(dp[u][1] < dp[v][0] + w)dp[u][1] = dp[v][0] + w;}}//枚举经过每个节点的长链,是否最大? ans = max(ans, dp[u][1] + dp[u][0]);
}int main()
{memset(head, 0, sizeof(head));scanf("%d", &n);for(int i = 1; i <= n - 1; i++){int u, v, w;scanf("%d%d%d", &u, &v, &w);Add(u, v, w);Add(v, u, w);}DFS(1, -1);  //假设1作为无根树的树根; printf("%d\n",ans);
}

从下往上推的话

首先是3,4的最长链,次长链都没有,=0,所以ans还是0

其次是2,先遍历3,最长=0+4,然后来,4,次长=最长=4,最长=0+5,ans=4+5=9

然后是5,最长次长都是0,ans不变

最后是1,最长=5+1,次长=0+2,总和=8<9,ans不变还是9

所以最长就是9,是3->2->4这条

可见,树的直径不一定经过根节点!

方法二:先找距离根节点最远的点,再找距离这个点最远的点(2次dp)

这是代码
  //https://blog.csdn.net/Rainfoo/article/details/105290837
//图论-树-最长链(树的直径) 
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
#define ll long long
const int maxn=2e5+5;
int d[maxn],head[maxn],f_num,ans,tot;
struct E{int to,next,w;
}edge[maxn];
void add(int u,int v,int z){edge[tot].to=v;edge[tot].w=z;edge[tot].next=head[u];head[u]=tot++;
}
void dfs(int x,int fa){if(ans<d[x]){ans=d[x];f_num=x;}for(int i=head[x];i!=-1;i=edge[i].next){int v=edge[i].to;if(v==fa) continue;d[v]=d[x]+edge[i].w;dfs(v,x);}
}
int main(){memset(head,-1,sizeof(head));int n,m;cin>>n>>m;for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v;//cin>>w;add(u,v,w);add(v,u,w);}dfs(1,0);ans=0;d[f_num]=0;dfs(f_num,0);cout<<ans<<endl;
}

从1开始找,最远的点是4,

再从4开始找,最远的节点是3

注意,这里dfs函数中的fa参数指的并不是真正的父节点,只是从哪里来的,即上一个节点

然后这是这道题

只不过所有边的权值都是1罢了

然后n起到一个什么作用呢?

这个n既不是根节点,也不是起点或终点

它只起到一个限定作用,限定所有变换中的数必须<=n

数字转换
 #include<iostream>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int INF=0x3f3f3f;
const double eps=1e-5;
const int maxn=5e4+10;
/*题意:若是一个数x的所有约数(不包括他自己)之和sum比他自己小,
那么x可以转化成sum,sum也可以成 x。例如 4可以变为 3,1可以变为7
限制所有数字变换在不跨越 n的正整数范围内举行转化,求不停举行数字变换且无重复数字的最多变换步数*/
int sum[maxn];//预处理每个数的约数之和
int f1[maxn],f2[maxn];//f1:以i为根的树中,i到叶子节点的最长距离,f2 :....次长距离
//直径就是 max(f1[i]+f2[i])  就是树中所有的两点最短距离中的最大值
//
int n;
void getsum()//预处理每个数的约数之和
{for(int i=1;i<=n;i++){for(int j=2;j<=n/i;j++){sum[i*j]+=i;  //i是i*j的约数 }}
}
int main()
{
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);scanf("%d",&n);getsum();for(int i=n;i>=1;i--){if(sum[i]>=i)  continue;//把sum[i]看成i的父亲,因为每个i的sum[i]都是唯一的 而能变成i的数不唯一if(f1[i]+1>f1[sum[i]]) {f2[sum[i]]=f1[sum[i]];f1[sum[i]]=f1[i]+1;}else if(f1[i]+1>f2[sum[i]]) f2[sum[i]]=f1[i]+1;}int ans=-1;for(int i=1;i<=n;i++) ans=max(ans,f1[i]+f2[i]);printf("%d\n",ans);return 0;
}

  • 皇宫看守

这是一道树形dp题

简单说下思路就行:一个点必须要被看守,那么有三种情况:

在这个点安排守卫,父亲安排守卫,孩子安排守卫

1.在这个点安排守卫,就需要付自己的钱和孩子的钱

优点:没啥顾虑,这个点一定有人看守

缺点:费钱

2.父亲安排守卫就,只需要付孩子的钱就行

优点:省钱

缺点:条件苛刻,必须要父亲自己看守才能使用

3.让孩子安排守卫,只需要付孩子的钱就行

优点:还是省钱

缺点:如果所有孩子都不愿意自己看守(即所有孩子自己看守的花费>让孩子的孩子看守孩子的花费)

          这时候必须要强制把一个孩子拉出来干活,即fake

这是代码
 // 皇宫看守 loj 10157 
//  https://www.cnblogs.com/Forever-666/p/11234958.html 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=2200;
struct E{int x,y,next;}mm[MAXN<<1];
int w[MAXN],h[MAXN],len,f[MAXN][3],n;void ins(int x,int y)
{++len;mm[len].x=x;mm[len].y=y;mm[len].next=h[x];h[x]=len;
}
void dfs(int x,int fa)
{int sum1=0,sum2=0,flag=0,fake=0x7fffffff;for(int k=h[x];k;k=mm[k].next){int y=mm[k].y;if(y==fa) continue;dfs(y,x);sum1+=min(f[y][0],min(f[y][1],f[y][2]));if(f[y][0]<=f[y][2]){sum2+=f[y][0];flag=1;}else {sum2+=f[y][2];fake=min(fake,f[y][0]-f[y][2]);	 //防止所有的孩子都不选,选一个最小的 }}f[x][0]=sum1+w[x];  //f[i][0]: 自己站 f[x][1]=sum2;       //f[i][1]:被父亲照顾 f[x][2]=sum2;       //f[i][2]:被孩子照顾 if(!flag) f[x][2]+=fake;
}
int main()
{scanf("%d",&n);memset(h,0,sizeof h);len=0;for(int i=1,x,t,y;i<=n;i++){scanf("%d",&x);scanf("%d%d",&w[x],&t);for(int j=1;j<=t;j++){scanf("%d",&y);ins(x,y);ins(y,x);}if(t==0){f[x][1]=0;f[x][0]=f[x][2]=w[x];}}dfs(1,0);printf("%d\n",min(f[1][0],f[1][2]));for(int i=1;i<=n;i++)cout<<f[i][0]<<" "<<f[i][1]<<" "<<f[i][2]<<"\n"; return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888189.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真

1.课题概述基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真。利用电压外环PI调节器得到有功 电流指令值结合由负载侧电流检测 到 的无功 电流指令值 ,经由 状态解耦PI调节的电流内环控制器输出直接得到的是输出电压的指令值,用此信号作为采用控制…

【库】Coravel Schedule任务调度

Coravel 通过使高级应用程序功能(如任务/作业调度、排队、缓存、邮件(以及更多!))易于访问且易于使用,帮助开发人员快速启动并运行 .NET 应用程序。具有简单、富有表现力和直接的语法。   下面是简单的用法,通过注入Scheduler和在中间件中定义调度的实现,来完成简单的…

【库】用Rin透视Web请求

Rin 可以捕获对 ASP.NET Core 应用程序的 HTTP 请求,并为捕获的数据提供查看器。它是调试 Web 应用程序(例如,网站、API 应用)的有用工具。先看如下代码:var builder = WebApplication.CreateBuilder(args); builder.Logging.AddRinLogger(); builder.Services.AddRin(); …

【蓝桥训练记录】第 26 场 蓝桥月赛

训练情况赛后反思 这场怎么都是猜猜乐+典题,做不出来的题真的不会了 A题 显然 2025 里面有多少个 15,除法向上取整即可点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;void solve(){cout<<ceil(1.0*2025/15…

光纤三维布里渊温度和应变分布matlab模拟与仿真

1.程序功能描述 光纤三维布里渊温度和应变分布matlab模拟与仿真。其中 , 布里渊散射是光波与声波在光纤中传播时相互作用而产生的光散射过程 , 在不 同的条件下 , 布里渊散射又分别以自发散射和受激散射两种形式表现出来 。 2.测试软件版本以及运行结果展示MATLAB2022A版…

基于一阶梯度的图像亚像素位移matlab仿真,带GUI界面

1.算法运行效果图预览 (完整程序运行后无水印)2.算法运行软件版本 matlab2022a3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)% --- Executes on button press in checkbox1. function checkbox1_Callback(hObject, eventdata, handles) % hObject handle to…

Java基础学习(十六)

Java基础学习(十六):多线程 目录Java基础学习(十六):多线程概念多线程的实现方式常见成员方法线程安全问题同步代码块同步方法Lock 锁生产者消费者模式(等待唤醒机制)线程池 本文为个人学习记录,内容学习自 黑马程序员概念进程:程序的基本执行实体 线程:操作系统能够…

AXI4-Stream Data FIFO(2.0)

IP核具体设置如下,数据宽度64bit,深度32,启用了包传输。打开Example Design三个IP核和两个AXI读写模块。 clk_wiz_0是mmcm IP核,提供工作时钟,proc_sys_reset_0是系统复位 IP核,提供复位信号,axis_data_fifo是本次的仿真IP 核。 axis_data_fifo_example_master是写模块,…

DeepSeek宣布下周开源5大项目,这才是真OpenAI!

近日,DeepSeek 团队宣布将在下周连续开源 5 个项目。这一举措不仅吸引了众多开发者的目光,还在技术社区引发了热烈讨论,不少网友甚至将 DeepSeek 誉为 “真正的 OpenAI”。一、DeepSeek开源计划详情(一)开源时间与方式DeepSeek团队决定开展“OpenSourceWeek”(开源周)活…

NOIP 2024 游记 | Loser.

Loser. p.s. 本文章比较废话()Day 1 早上 6:30 被拽起来了。吃饭。出门。坐地铁。到! 华科大门,比,华师气派多了诶诶。扯了个横幅,拍照。拍照。拍照。 诶诶,怎么 7:45 就拽着我们进去了。 进考场。我怎么是第一排第一个 /jk 看见了 @Hakureireimu_cjrljpx,但是他不认识…

利用 vscode 进行远程开发

打开远程项目路径在远程服务器上安装 vscode 插件 Go、GitLens、Git History、Git Graph、MarsCode AI对于本地已经安装的插件,点击Install In SSH:xxx就能把插件安装到远程服务器对于本地没有安装的插件,直接查找插件,选中安装,即是安装到远程服务器git 不高亮显示修改行从…