马上蓝桥了,干货总结基础树论知识点

2024-04-02 15:04

本文主要是介绍马上蓝桥了,干货总结基础树论知识点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

今日知识点:
对于每个子树如果和小于0就返回0;如果大于0就直接返回。

注意异或的性质,偶消奇不消,所以lca上面的都消掉了,并不需要跑lca,也就是说只需要把根到所有点的距离跑出来即可

如果上传过来小于k个,我们是考虑把当前根节点也加入其中;如果大于k,那就直接返回失败;等于k忽略

这棵树的深度就是这棵树上到根节点的最长距离+1;这棵树的宽度就是到根节点距离相同的节点个数的最大值

最大子树和

思路: 

树上异或

思路: 

树的分解

思路: 

二叉树问题

思路: 


        

        

最大子树和

思路: 

对于每个子树:如果子树和小于0,直接丢掉吧,所以返回0;如果大于0就直接返回。

#include <bits/stdc++.h>
using namespace std;
const int N=2e4;
typedef long long ll; 
vector<int>ve[N];
ll ans,n,a[N],f[N],INF=-1e11;
int dfs(int u,int fa){for(int i=0,sz=ve[u].size();i<sz;i++){int v=ve[u][i];if(v==fa)continue;f[u]+=dfs(v,u);}f[u]+=a[u];ans=max(f[u],ans);if(f[u]<0)return 0;else return f[u];
}
int main(){cin>>n;int x,y;ans=INF;for(int i=1;i<=n;i++){cin>>a[i];}for(int i=1;i<=n-1;i++){cin>>x>>y;ve[x].push_back(y);ve[y].push_back(x);}dfs(1,-1);cout<<ans;
}

        

        

树上异或

思路: 

注意异或的性质,偶消奇不消,所以lca上面的都消掉了,并不需要跑lca(你喜欢写LCA代码吗?)也就是说只需要把根到所有点的距离跑出来即可

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int tot,n,m,head[N],f[N];
struct node{int to,w,next;}e[N*2];
void add(int u,int v,int w){e[++tot]={v,w,head[u]};head[u]=tot;}
void dfs(int u,int fa,int num){f[u]=num;for(int i=head[u];i;i=e[i].next){int v=e[i].to,w=e[i].w;if(fa==v)continue;dfs(v,u,num^w);}
}
int main(){cin>>n;int u,v,w;for(int i=1;i<n;i++){scanf("%d%d%d",&u,&v,&w);add(u,v,w);add(v,u,w);	}dfs(1,0,0);cin>>m;for(int i=1;i<=m;i++){scanf("%d%d",&u,&v);printf("%d\n",f[u]^f[v]);	}return 0;
}

        

        

树的分解

思路: 


此题不好做,首先要明白最终的效果,必然是k个联通的,那么对于每个节点来说,如果孩子匹配不成功,是可以和父亲继续匹配的,也就是上传当前个数即可。

那么对于节点来说:一定是和上传过来的未匹配成功的孩子都保持一个颜色,
否则就联通不了,你可以画图证明。(因为如果匹配成功就可以忽略)

那么如果上传过来小于k个,我们是考虑把当前根节点也加入其中;如果大于k,那就直接返回失败;等于k忽略

#include <bits/stdc++.h>
using namespace std;
int n,k,t,sum;
vector<int>ve[100005];
int dfs(int u,int fa){int ans=1;//初始化上传数for(int i=0,sz=ve[u].size();i<sz;i++){if(ve[u][i]==fa)continue;int a=dfs(ve[u][i],u);if(a==-1||a>k)return -1;//这段还认识吗,高速公路哦else if(a==k)continue;//直接上传0ans+=a;//更新上传数}return ans;
}
int main(){cin>>t;while(t--){cin>>n>>k;int a,b;for(int i=0;i<=n;i++)ve[i].clear();for(int i=1;i<n;i++){cin>>a>>b;ve[a].push_back(b);ve[b].push_back(a);}int ans=dfs(1,1);if(ans==k)cout<<"YES\n";//包括根节点在内仅上传k个则代表成功分解else cout<<"NO\n";}return 0;
}

        

        

二叉树问题

思路: 

树的深度好说,宽度很容易让人想到树的直径(【算法每日一练]-图论(保姆级教程篇16 树的重心 树的直径)#树的直径 #会议 #医院设置-CSDN博客)感兴趣可以看看啊!

但是!!!这俩玩意不是一个东西哈,直径是直径,宽度是宽度。

现在要求查询这棵树的深度,其实就是这棵树上到根节点的最长距离+1;查询这棵树的宽度,其实就是到根节点距离相同的节点个数的最大值

要处理第3个问题,一个很巧妙的做法是直接就把指向叶子方向的边权设为1,指向根方向的边权设为2。然后最短路即可

#include <bits/stdc++.h>
using namespace std;//拿图
const int N=200;
int n,ans,tot,dis[N],vis[N],head[N],tmp[2000];
struct node{int to,w,next;}e[N*2];
void add(int u,int v,int w){e[++tot]={v,w,head[u]};head[u]=tot;}
void spfa(int s){queue<int>q;q.push(s);memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));vis[s]=1;dis[s]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=head[u];i;i=e[i].next){int v=e[i].to,w=e[i].w;if(dis[v]>dis[u]+w){dis[v]=dis[u]+w;if(!vis[v]){vis[v]=1;q.push(v);}}}}
}
int main(){cin>>n;int u,v;for(int i=1;i<n;i++){//树是n点n-1边cin>>u>>v;add(u,v,1);add(v,u,2);}cin>>u>>v;spfa(1);for(int i=1;i<=n;i++)tmp[dis[i]]++,ans=max(ans,dis[i]);cout<<ans+1<<'\n';ans=0;for(int i=1;i<=2000;i++)ans=max(ans,tmp[i]);cout<<ans<<'\n';spfa(u);cout<<dis[v]<<'\n';
}

这篇关于马上蓝桥了,干货总结基础树论知识点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870297

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close