zoj2838 &&倍增法
来源:互联网 发布:naim muso淘宝假货 编辑:程序博客网 时间:2024/05/16 05:05
//离线算法是在dfs过程中进行相连两点的寻找最近祖先,
//在线算法是dfs结束后直接查找相连两点的最近祖先
#include <iostream>#include <stdio.h>#include <algorithm>#include <vector>#include <string.h>using namespace std;const int n=50002;vector<int> g[n];//表示图(树)int nn;int p[n][20];//表示向上翻2^i代的祖先节点int vis[n],s[n];//s[i]表示2^iint deep[n];//表示点i的深度int dfs(int u,int fa,int dep)//作用:得到了第1代的祖先节点,得出树的深度{ int tree_deep=dep; deep[u]=dep; p[u][0]=fa;//u的第2^0代祖先是u的父亲 vis[u]=1; int len=g[u].size(); for(int i=0;i<len;i++) { int v=g[u][i]; if(vis[v]==0) { tree_deep=max(tree_deep,dfs(v,u,dep+1));//tree_deep是树的深度 } } return tree_deep;}void init(){ memset(vis,0,sizeof vis); memset(p,-1,sizeof p); int tree_deep=dfs(0,-1,1);//tree_deep是树的深度 for(int i=1;s[i]<=tree_deep;i++)//依次得出2^i代的祖先节点 { for(int j=1;j<n;j++)//依次得出节点j的2^i代的祖先节点 if(p[j][i-1]!=-1) { int tmp=p[j][i-1];//tmp是j点的第2^(i-1)代祖先 p[j][i]=p[tmp][i-1];//p[j][i]是j的第2^i代祖先,也就是tmp的第2^(i-1)代祖先 } }}int lca(int x,int y){ if(deep[x]<deep[y]) x^=y,y^=x,x^=y;//确保节点x比y深 int log; for(log=0;s[log]<=deep[x];log++);//2^log是x向上移动代数的上限 log--; for(int i=log;i>=0;i--) { if(deep[x]-s[i]>=deep[y])//如果向上移动2^i代没有超过y那代 x=p[x][i];//x向上移动2^i代 } if(x==y) return x;//上面那个for循环使得x和y在同一代上,如果刚好x就是y,返回x for(int i=log;i>=0;i--)//从上限开始for循环遍历 { if(p[x][i]!=-1 && p[x][i]!=p[y][i])//已经在同一代的x,y同时向上移动2^i,确保没有”移过头“(就是p[x][i]=-1) x=p[x][i],y=p[y][i]; //还要确保p[x][i]=p[y][i]才能向上移动 } return p[x][0];}int main(){ s[0]=1; for(int i=0;i<19;i++) s[i+1]=s[i]*2; int t=1; while(~scanf("%d",&nn)) { int x,y,z; if(t!=1)printf("\n"); printf("Case %d:\n",t++); for(int i=0;i<=n;i++) g[i].clear(); for(int i=1;i<nn;i++) { scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } init(); int mm;scanf("%d",&mm); for(int i=1;i<=mm;i++) { scanf("%d%d%d",&x,&y,&z); int a=lca(x,y); if(deep[a]<=deep[z]) { if(lca(x,z)==z || lca(y,z)==z) { printf("Yes\n"); continue; } } printf("No\n"); } } return 0;}
阅读全文
0 0
- zoj2838 &&倍增法
- 倍增法
- ZOJ2838【LCA在线查询】
- 倍增法的妙用
- 【LCA】倍增法 LCA
- LCA倍增法模板
- 矩阵倍增法uva11149
- 倍增法求LCA
- LCA倍增法
- hdu5266 LCA 倍增法
- LCA倍增法
- lca倍增法
- LCA倍增法
- 倍增法求LCA
- 在线LCA倍增法
- 后缀数组倍增法
- 倍增法求LCA
- 倍增法求LCA
- Linux文件系统编程
- 是什么使一名好程序员变得伟大
- springrain
- dedecms 如何修补XSS跨站脚本攻击
- 3361 数据结构实验之图论四:迷宫探索
- zoj2838 &&倍增法
- 支持向量机(SVM)原理与实践(一)
- 2017年乌镇互联网大会嘉宾分享要点实录
- 【Learning】Link-Cut Tree
- java.lang.NullPointerException(日志)(171204
- 小米5S刷机认真看一眼就能会的简单详细教图文
- 微信小程序开发-五星评价
- Raspbian Ubuntu下安装OpenCV2.4.9的详细过程及碰到的问题和第一次程序的编译调试
- centos7配置jdk环境