• P1087 FBI树
  • P1030 求先序排列
  • P1305 新二叉树
  • P1229 遍历问题
  • P5018 对称二叉树
  • P5597 【XR-4】复读
  • P2195 HXY造公园
  • P3629 [APIO2010]巡逻
  • P5536 【XR-3】核心城市
  • P1099 树网的核
  • P4408 [NOI2003]逃学的小孩

1.P1087 FBI树

递归求解,判断是否为’0’串或者’1’串即可

#include<bits/stdc++.h>
using namespace std;
string a;
int n;
void chuan(string x){if(x.length()>0){int len=x.length();chuan(x.substr(0,len/2));chuan(x.substr(len/2,len-1));if (x == string(x.length(), '0')) cout<<'B';else if (x == string(x.length(), '1')) cout<<'I';else{cout<<'F';}}
}
int main(){cin>>n>>a;chuan(a);return 0;
}

2.P1030 求先序排列

给出了中序和后序排列,求先序排列
由这两种输出方式的性质可知,根在后序的最后输出,所以我们找到根为分界线,不断递归为两个子树进行求解

#include<bits/stdc++.h>
using namespace std;
string a,b;
void dfs(string x,string y){if(x.length()>0){int len=y.length();cout<<y[len-1];char ch=y[len-1];int t=x.find(ch);dfs(x.substr(0,t),y.substr(0,t));dfs(x.substr(t+1,len-1),y.substr(t,len-t-1));}
}
int main(){cin>>a>>b;dfs(a,b);return 0;
}

3.P1305 新二叉树

给一棵树,输出先序遍历,直接递归即可

#include<bits/stdc++.h>
using namespace std;
struct node{char lc,rc;
}t[200];
char t1,tt;
void xianxu(char x){if(x=='*') return;cout<<x;xianxu(t[x].lc);xianxu(t[x].rc);
}
int main(){int n;cin>>n;cin>>t1;cin>>t[t1].lc;cin>>t[t1].rc;for(int i=2;i<=n;i++){cin>>tt;cin>>t[tt].lc;cin>>t[tt].rc;}xianxu(t1);return 0;
}

4.P1229 遍历问题

给出先序和后序遍历,求这棵树最多有多少种不同中序遍历的情况
中序+x 可以求出这棵树
转化一下题意就是求有多少个子树只有一个儿子

#include<bits/stdc++.h>
using namespace std;
string a,b;
int main(){cin>>a;cin>>b;int ans=0;int n=a.length();for(int i=0;i<n;i++){for(int j=1;j<n;j++){if(a[i]==b[j]&&a[i+1]==b[j-1]){ans++;}}}printf("%d",1<<ans);
}

5.P5018 对称二叉树

遍历每一个节点,递归判断子树是否对称,并更新最大值

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{int l,r,w;
}t[1000005];
int n;
bool same(int x,int y){if(x==-1&&y==-1)return true;if(x==-1||y==-1)return false;if(t[x].w!=t[y].w)return false;return same(t[x].l,t[y].r)&&same(t[x].r,t[y].l);
}
int ct(int x){return x==-1?0:ct(t[x].l)+ct(t[x].r)+1;
}
signed main(){cin>>n;for(int i=1;i<=n;i++){scanf("%lld",&t[i].w);}for(int i=1;i<=n;i++){scanf("%lld%lld",&t[i].l,&t[i].r);}int ans=0;for(int i=1;i<=n;i++){if(same(i,i))ans=max(ans,ct(i));}cout<<ans;return 0;
}

6.P5597 【XR-4】复读

咕咕咕待补

7.P2195 HXY造公园

操作1,输出该点所在的树的直径
操作2,将u,v所在的树连接,并且要求连接后的树的直径尽量小
怎么实现操作2?选两个直径的中点进行合并

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
int f[maxn],c[maxn],vis[maxn],n,m,q,g[maxn],d[maxn],len;
vector<int>e[maxn];
int find(int x){if(x==f[x])return x;return f[x]=find(f[x]);
}
void dfs(int x,int fa){int m1=-1,m2=-1;for(int i=0;i<e[x].size();++i){int y=e[x][i];if(y==fa)continue;dfs(y,x);int tmp=d[y]+1;d[x]=max(d[x],tmp);if(tmp>m1)m2=m1,m1=tmp;else if(tmp>m2)m2=tmp;}g[x]=max(max(0,m1+m2),max(m1,m2));len=max(len,g[x]);
}
void calc(int x)
{len=0;dfs(x,0);c[x]=len;
}
int main(){cin>>n>>m>>q;for(int i=1;i<=n;i++){f[i]=i;}for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);e[u].push_back(v);e[v].push_back(u);f[find(u)]=find(v);}for(int i=1;i<=n;i++){if(f[i]!=i||vis[i])continue;calc(i);vis[i]=1;}int tt,u,v;while(q--){scanf("%d",&tt);if(tt==1){scanf("%d",&u);printf("%d\n",c[find(u)]);continue;}scanf("%d%d",&u,&v);int x=find(u);int y=find(v);if(x==y)continue;int t=((c[x]+1)/2)+((c[y]+1)/2)+1;t=max(t,max(c[x],c[y]));f[find(x)]=find(y);c[find(x)]=t;}return 0;
}

8.P3629 [APIO2010]巡逻

有两种情形,k=1的时候只需要找到直径,连接两端即可
k=2时,如果连接的边经过了第一条路径,就要再走一遍,所以把第一条已经连好的路上权值取负
x-y-(-y)=x
由于dfs求直径不能处理负数,所以用dp求,也是这个题的精髓所在,需要用dfs求直径来记录路径,用dp来处理负权

#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
int head[maxm],dis[maxm],n,k,cnt=1,pos,st,ed;
int f[maxm],vis[maxm];
struct edge{int v,w,nex;
}e[maxm];
inline void add(int u,int v){e[++cnt].v=v;e[cnt].w=1;e[cnt].nex=head[u];head[u]=cnt;
}
void dfs(int u,int fa){if(dis[u]>dis[pos]||pos==st)pos=u;f[u]=fa;for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa)continue;dis[v]=dis[u]+e[i].w;dfs(v,u);}return;
}
void change(int u,int fa){for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa)continue;if(vis[v]){e[i].w=-1;e[i^1].w=-1;}change(v,u);}return;
}
int l2;
void dp(int u,int fa){for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa)continue;dp(v,u);l2=max(dis[v]+dis[u]+e[i].w,l2);dis[u]=max(dis[u],dis[v]+e[i].w);}return;
}
int main(){cin>>n>>k;int u,v;for(int i=1;i<=n-1;i++){scanf("%d%d",&u,&v);add(u,v);add(v,u);}st=1;pos=1;dis[1]=0;dfs(st,0);st=pos;dis[st]=0;dfs(st,0);ed=pos;int l1=dis[ed];int r=ed;while(r){vis[r]=1;r=f[r];}change(st,0);memset(dis,0,sizeof(dis));dp(st,0);if(k==1)l2=1;int ans=n*2-l1-l2;cout<<ans;return 0;
}

9.P5536 【XR-3】核心城市

在树中间选一些点,使其他点到这些点的最大距离最小
先求直径,再求中点,中点一定要被选中,然后以中点为根建树,进行一次dfs,统计每个点向下延伸的最大深度,对子节点进行排序,显然第k+1个节点+1即为答案(因为记录的是最大延伸,需要加上自己与核心城市的距离1)

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int n,k,head[maxn],f[maxn],st,ed,pos,dis[maxn],cnt,vis[maxn],len[maxn];
struct edge{int v,w,nex;
}e[maxn];
vector<int>ve;
inline void add(int u,int v){e[++cnt].v=v;e[cnt].w=1;e[cnt].nex=head[u];head[u]=cnt;
}
void dfs(int u,int fa){if(dis[u]>dis[pos]||pos==st)pos=u;f[u]=fa;for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa)continue;dis[v]=dis[u]+1;dfs(v,u);}return;
}
void dfs3(int sn,int fa){len[sn]=0;for(int i=head[sn];i;i=e[i].nex){int v=e[i].v;if(v!=fa){dfs3(v,sn);len[sn]=max(len[sn],len[v]+1);}}
}
bool cmp(int x,int y){return x>y;
}
int main(){cin>>n>>k;for(int i=1;i<=n-1;i++){int u,v;scanf("%d%d",&u,&v);add(u,v);add(v,u);}st=1,pos=1,dis[1]=0;dfs(st,0);st=pos,dis[st]=0;dfs(st,0);ed=pos;int l1=dis[ed];int st2=ed;for(int i=1;i<=(l1+1)/2;i++){st2=f[st2];}dfs3(st2,0);sort(len+1,len+1+n,cmp);cout<<len[k+1]+1;return 0;
}

10.P1099 树网的核

P2491 [SDOI2011]消防
U89620 树网的核加强版
这两题是数据加强板(三倍经验)
前提是用最优解做的
直接上数据最强的一个版本的代码

大体的思路是这样的,先用dfs求出直径,然后从端点进行遍历,选择每一段小于等于s的路径,求出两端点到这段路径的最小距离,
然后求出每个直径上的点到这个点的最小距离,跟ans进行比较

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int n,s,head[maxn],f[maxn],st,ed,pos,dis[maxn],cnt,vis[maxn],len[maxn];
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w,nex;
}e[maxn];
inline void add(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].nex=head[u];head[u]=cnt;
}
void dfs(int u,int fa){if(dis[u]>dis[pos]||pos==st)pos=u;f[u]=fa;for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa||vis[v]==1)continue;dis[v]=dis[u]+e[i].w;dfs(v,u);}return;
}
void dfs2(int u,int fa){for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa||vis[v]==1)continue;dis[v]=dis[u]+e[i].w;dfs(v,u);}return;
}
int main(){cin>>n>>s;int u,v,w;for(int i=1;i<=n-1;i++){u=read(),v=read(),w=read();add(u,v,w);add(v,u,w);}st=1,pos=1,dis[1]=0;dfs(st,0);st=pos,dis[st]=0;dfs(st,0);ed=pos;int ans=0x3f3f3f3f;int tmp=ed;for(int i=ed;i;i=f[i]){while(f[tmp]&&dis[i]-dis[f[tmp]]<=s){tmp=f[tmp];}ans=min(ans,max(dis[ed]-dis[i],dis[tmp]));}for(int i=ed;i;i=f[i]){vis[i]=1;dis[i]=0;}
//  cout<<ed<<endl;
//  for(int i=1;i<=n;i++){//      printf("%d %d  vis:%d\n",i,f[i],vis[i]);
//  }for(int i=ed;i;i=f[i]){dfs2(i,0);}for(int i=1;i<=n;i++){if(!vis[i]){ans=max(ans,dis[i]);}}cout<<ans;return 0;
}

11.P4408 [NOI2003]逃学的小孩

求非直径上的点到直径的两端点的最大值

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=4e5+5;
int dis2[maxn],dis3[maxn];
int n,m,head[maxn],f[maxn],st,ed,pos,dis[maxn],cnt,vis[maxn],len[maxn];
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w,nex;
}e[maxn];
inline void add(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].nex=head[u];head[u]=cnt;
}
void dfs(int u,int fa){if(dis[u]>dis[pos]||pos==st)pos=u;f[u]=fa;for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa)continue;dis[v]=dis[u]+e[i].w;dfs(v,u);}return;
}
void dfs2(int u,int fa){for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa||vis[v]==1)continue;dis2[v]=dis2[u]+e[i].w;dfs2(v,u);}return;
}
void dfs3(int u,int fa){for(int i=head[u];i;i=e[i].nex){int v=e[i].v;if(v==fa||vis[v]==1)continue;dis3[v]=dis3[u]+e[i].w;dfs3(v,u);}return;
}
signed main(){cin>>n>>m;int u,v,w;for(int i=1;i<=m;i++){u=read(),v=read(),w=read();add(u,v,w);add(v,u,w);}st=1,pos=1,dis[1]=0;dfs(st,0);st=pos,dis[st]=0;dfs(st,0);ed=pos;int ans=dis[ed];dfs2(st,0);dfs3(ed,0);
//  for(int i=1;i<=n;i++){//      printf("i=%d dis2 %d dis3 %d\n",i,dis2[i],dis3[i]);
//  }int tmp=0;for(int i=1;i<=n;i++){int d=min(dis2[i],dis3[i]);tmp=max(tmp,d);}cout<<ans+tmp;return 0;
}

能力提升综合题单Part 8.3.1 二叉树Part 8.3.2 树的直径相关推荐

  1. 洛谷 能力提升综合题单Part1 入门阶段 P1089 津津的储蓄计划 带注释

    题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在 ...

  2. 蔡丹红老师刁酒集团《基层管理人员综合能力提升培训班》企业内训开讲

    蔡丹红老师:刁酒集团<基层管理人员综合能力提升培训班>企业内训开讲 一线员工总是奋斗在前线,为公司打开销路.打开渠道,为公司创造业绩,作为基层管理人员应做好本职工作,努力提升自己,提高综合 ...

  3. 软件技术专业大学生该如何制定职业综合能力提升计划

    记得那还是五年级的时候,那时班主任叫我们写上自己的理想吧.我就记得自己写了成为一个对社会有用的人,而别的同学都写上科学家和老师等等.但随着不断的成长,我们都走上了自己特定的人生轨道.这个时候我们不能再 ...

  4. 《大数据实践课》开创实践教学新模式:清华大数据能力提升项目特色课程系列报道之一

    2014年4月,清华大学顺应时代潮流成为全国第一批成立大数据研究机构的高等学府.四年来,清华-青岛数据科学研究院(以下简称:数据院)与研究生院共同设计组织实施了以大数据能力提升项目为主的大数据人才培养 ...

  5. 计算机网络技术综合题大全

    第1章 计算机网络概述 一.简答题 1.简述计算机网络的发展过程. 答:从1946年世界上第一台计算机ENIAC的诞生到现在网络的全面普及,计算机网络的发展大体可以分为以下4个阶段: (1)第一代计算 ...

  6. 教师计算机培训重要性日志,2018教师信息技术应用能力提升专题培训研修日志...

    <2018教师信息技术应用能力提升专题培训研修日志>由会员分享,可在线阅读,更多相关<2018教师信息技术应用能力提升专题培训研修日志(3页珍藏版)>请在人人文库网上搜索. 1 ...

  7. 计算机教学能力提升体会,教师信息技术能力提升学习心得

    教师信息技术能力提升学习心得 发布时间:2019-09-17 导语:当今以计算机和网络技术为核心的现代技术正飞速的发展,改变我们的学习方式,信息的获取.分析.处理.应用的能力将作为现代人最基本的能力和 ...

  8. 继续教育研修计算机总结与反思,教师信息技术能力提升研修反思日志

    教师信息技术能力提升研修反思日志 随着信息技术的不断发展,多媒体教学.信息技术平台等成为活跃课堂.调动学生学习积极性的一种主要手段."国培计划"为提高教师的自身水平提供了良好的平台 ...

  9. 功能点方法论助力南京银行信息科技量化管理能力提升

    由南京银行股份有限公司供稿的"功能点方法论助力南京银行信息科技量化管理能力提升" 一文,被<金融电子化>采稿并于2019年8月刊(总287期刊)上发表,于2019年8月 ...

  10. 四川省中小学应用计算机技术,四川省中小学教师信息技术应用能力提升工程研修互动交流...

    相关热词搜索:互动 信息技术 研修 中小学教师 提升 四川信息技术提升工程 四川省中小学教师提升 四川教师信息技术能力 篇一:四川省中小学教师信息技术应用能力提升工程 四川省中小学教师信息技术应用能力 ...

最新文章

  1. Qt5下OpenGL程序的新写法
  2. GitHub Copilot 支持 IntelliJ IDEA啦,插件装起来!
  3. 网络爬虫:基于对象持久化实现爬虫现场快速还原
  4. 全球及中国斜交胎市场品牌竞争形势与投资策略分析报告2022年
  5. libgcc_s.so.1 mysql_libgcc_s.so.1 must be installed for pthread_cancel to work | 学步园
  6. 【BZOJ3930】选数(莫比乌斯反演倍数形式,杜教筛)
  7. html5 css 三角形,css怎么画三角形?
  8. container_of详解
  9. Iometer存储测试工具参数说明-图形主界面(整理)
  10. 尚硅谷Linux视频学习建议贴及linux全套视频,运维版本180G高质量视频教程免费下,linux教程
  11. Go语言Web框架gwk介绍 (四)
  12. 一文读懂什么是数据库事务
  13. 理解Android编译命令
  14. [转]C#用SHA对密码加密
  15. rzsz工具 源码交叉编译
  16. 打包工具SetupFactory 9 的使用
  17. 再见也是永别——告别即将消逝的雅虎邮箱
  18. u盘打不开,提示需要格式化怎么办?
  19. 互联网+是什么意思?
  20. Where are Docker images stored? (杂译)

热门文章

  1. 从维基百科到裴松之注三国志
  2. 广播域与冲突域的区别
  3. 【转】ASP.net2。0中解决无法获取 GridView 隐藏列值问题
  4. Visual C++ 2005 系列课程学习笔记-6
  5. 谁会成为中国互联网下一代英雄
  6. apache配置本地的虚拟主机
  7. linux标准mib,Linux系统中测试你的MIB值
  8. 南阳oj-----D的小L(algorithm全排列用法)
  9. 一阶低通滤波器方程_一阶RC低通滤波器和RC高通滤波器简介-模拟/电源-与非网...
  10. 闹钟流程_国际航班流程全攻略(中转+不同航空公司+中转换机场+航班变动)