首页 > 代码库 > hdu3078 建层次树+在线LCA算法+排序
hdu3078 建层次树+在线LCA算法+排序
题意:n个点,n-1条边构成无向树,每个节点有权,Q次询问,每次或问从a->b的最短路中,权第k大的值,/或者更新节点a的权,
思路:在线LCA,先dfs生成树0,标记出层数和fa[](每个节点的父亲节点)。在对每次询问,走一遍一次公共祖先路上
思路:在线LCA,先dfs生成树0,标记出层数和fa[](每个节点的父亲节点)。在对每次询问,走一遍一次公共祖先路上
的权,保持,快排。n*logn*q
#include<iostream> //187MS #include<algorithm> #include<cstdio> #include<vector> using namespace std; int n,q; int w[90000]; vector<vector<int> >e(160100); int lev[80010];int vis[80010]; int fa[80010]; void dfs_getlev(int u) //dfs { for(int i=0;i<e[u].size();i++) { int v=e[u][i]; if(!vis[v]) { vis[v]=1; lev[v]=lev[u]+1; fa[v]=u; dfs_getlev(v); } } } bool my(int a,int b) { return a>b; } int find_lca(int k,int a,int b) //在线lca,按层次向上走。 { vector<int> ans; if(lev[a]>lev[b]) { int temp=a;a=b;b=temp; } while(lev[b]>lev[a]) { ans.push_back(w[b]); b=fa[b]; } while(a!=b) { ans.push_back(w[b]); ans.push_back(w[a]); a=fa[a]; b=fa[b]; } ans.push_back(w[b]); if(k>ans.size()) return -1; sort(ans.begin(),ans.end(),my); return ans[k-1]; } int main() { cin>>n>>q; for(int i=1;i<=n;i++) scanf("%d",&w[i]); int ta,tb; for(int i=0;i<n-1;i++) { scanf("%d%d",&ta,&tb); e[ta].push_back(tb); e[tb].push_back(ta); } vis[1]=lev[1]=1; dfs_getlev(1); int k,a,b; while(q--) { scanf("%d%d%d",&k,&a,&b); if(k>0) { int anss =find_lca(k,a,b); if(anss!=-1) printf("%d\n",anss); else printf("invalid request!\n"); } else { w[a]=b; } } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。