POJ--1986--Distance Queries--LCA-RMQ
来源:互联网 发布:微信盗取软件 编辑:程序博客网 时间:2024/05/04 19:34
题目大意:求一棵树任意两点的距离
解题报告,设一个数组 dis[i]表示i节点到跟节点的距离,则任意两点的最短距离:dis[i,j]=dis[i]+dis[j]-2*dis[LCA(i,j)]
这个公式还是比较直接的吧
这样就转化成了一个LCA问题。召唤模板
就不吐槽WA到死的代码,换个节点存储方式就过了,简化的数据存储方式可以降低编程复杂度。
PS:此题中的东西南北的方向是不需要的
个人感觉就是1985加上个RMQ模板
#include<iostream>#include<cstring>#include<cstdio>#include<vector>#define maxn 51000using namespace std;vector<int> g[maxn]; //树的存储结构vector<int> elen[maxn]; //存储边权int r[maxn]; //RMQ问题中标记节点第一次在e数组中出现的位置int e[maxn*2]; //RMQ问题中深搜记录边访问的节点 int l[maxn*2]; //RMQ问题中记录节点的访问深度int dp[maxn*2][20]; int res[maxn*2][20];int ei,n,m,root,x,y;bool vis[maxn];int dis[maxn]; //dis[i]表示i节点到根节点的距离,此题中根节点是1void init(){ int x,y,l; char dir[10]; scanf("%d%d",&n,&m); memset(dis,0,sizeof(dis)); for(int i=1;i<=m;i++) { scanf("%d%d%d%s",&x,&y,&l,dir); g[x].push_back(y); elen[x].push_back(l); g[y].push_back(x); elen[y].push_back(l); }}void _dfs(int u) //深搜确定节点之间的继承关系以及以u为根节点的子树的最远叶子距离{ vis[u]=1; int v,vlen=g[u].size(); for(int i=0;i<vlen;i++) { v=g[u][i]; if(!vis[v]) { dis[v]=dis[u]+elen[u][i]; _dfs(v); } }}void rdfs(int u,int dep){ vis[u]=1; e[ei]=u; l[ei]=dep; r[u]=ei; ei++; int v,vlen=g[u].size(); for(int i=0; i<vlen; i++) { v=g[u][i]; if(!vis[v]) { rdfs(v,dep+1); e[ei]=u; l[ei]=dep; ei++; } }}void RMQ_init(){ for(int i=0; i<ei; i++) { dp[i][0]=l[i]; res[i][0]=e[i]; } for(int j=1; (1<<j)-1<ei; j++) { for(int i=0; i+(1<<j)<ei; i++) { x=dp[i][j-1]; y=dp[i+(1<<(j-1))][j-1]; if(x<y) { dp[i][j]=x; res[i][j]=res[i][j-1]; } else { dp[i][j]=y; res[i][j]=res[i+(1<<(j-1))][j-1]; } } }}int RMQ(int lx,int ly){ int len=0; while(lx+(1<<(len+1))-1<=ly)len++; x=dp[lx][len]; y=dp[ly-(1<<len)+1][len]; if(x<y)return res[lx][len]; else return res[ly-(1<<len)+1][len];}void solve(){ memset(vis,0,sizeof(vis)); _dfs(1); memset(vis,0,sizeof(vis)); ei=0; rdfs(1,1); RMQ_init(); int a,b; int ic,ans,x,px; scanf("%d",&ic); for(int i=0;i<ic;i++) { scanf("%d%d",&a,&b); if(r[a]>r[b])swap(a,b); int tar=RMQ(r[a],r[b]); ans=dis[a]+dis[b]-2*dis[tar]; printf("%d\n",ans); }}int main(){ freopen("1986.txt","r",stdin); init(); solve(); return 0;}
- POJ 1986 Distance Queries LCA和RMQ
- POJ--1986--Distance Queries--LCA-RMQ
- POJ 1986 Distance Queries (在线LCA转RMQ)
- POJ 1986 - Distance Queries(LCA‘ 在线算法RMQ)
- POJ 1986 Distance Queries 【RMQ LCA】双向存边
- POJ 1986 Distance Queries [LCA]
- poj 1986 Distance Queries LCA
- POJ 1986 Distance Queries(LCA)
- poj 1986 Distance Queries (LCA)
- POJ 1986 Distance Queries LCA
- [POJ 1986] Distance Queries (LCA)
- Distance Queries - POJ 1986 LCA
- poj 1986 Distance Queries(LCA)
- POJ 1986 Distance Queries【LCA】
- Poj 1986 Distance Queries【LCA】
- POJ 1986 Distance Queries 【LCA】
- |poj 1986|LCA|Distance Queries
- poj 1986 Distance Queries 【LCA转RMQ 裸题】【求两点最短距离】
- su- 与su的区别
- day6 test01
- MIC编程(3)——MIC峰值性能计算方法
- 擅长排列的小明
- hust 1024 dance party
- POJ--1986--Distance Queries--LCA-RMQ
- java中的执行流程
- JUnit4概述
- POJ 2513 Colored Sticks 【Trie树】
- 酷毙了!滚动导航在单页网站中的应用《第二季》
- 什么是回调函数?
- 吝啬的国度
- <stdlib.h>中的随机数产生函数rand,random,srand,srandom的一些知识
- Win7使用心得