poj 1986(离线查询点对最近公共祖先)
2015-12-21 11:19
323 查看
题意:给一棵树,查询一些点对的距离
解法:随便找一个点建立有根树,然后转化为求点对最近公共祖先问题。两点的距离等于他们与最近祖先的距离和。查询的方法是dfs+并查集离线查询。思想是,dfs过的为回溯的点的parent全部指向自己本身,vis标记为true。回溯之后的点parent指向自己的父亲。然后dfs每进入一个点,就处理这个点相关的查询,如果其中某个查询另一个点v的vis为true,那么它们俩的最近公共祖先就是并查集中v的最终祖先。
代码:
解法:随便找一个点建立有根树,然后转化为求点对最近公共祖先问题。两点的距离等于他们与最近祖先的距离和。查询的方法是dfs+并查集离线查询。思想是,dfs过的为回溯的点的parent全部指向自己本身,vis标记为true。回溯之后的点parent指向自己的父亲。然后dfs每进入一个点,就处理这个点相关的查询,如果其中某个查询另一个点v的vis为true,那么它们俩的最近公共祖先就是并查集中v的最终祖先。
代码:
#include <cstring> #include <iostream> #include <cstdio> #include <vector> using namespace std; int n,m; const int Max=100100; struct edge { int v; int ran; int next; } edges[Max*2]; int head[Max]; int parent[Max]; int dis[Max]; int ans[Max]; int count1=0; vector<pair<int,int> > vec[Max]; bool vis[Max]; int getparent(int u) { if(u==parent[u]) return u; return parent[u]=getparent(parent[u]); } void add(int u,int v,int dis) { vec[u].push_back(make_pair(v,dis)); vec[v].push_back(make_pair(u,dis)); } void addedge(int u,int v,int r) { edges[count1].v=v; edges[count1].ran=r; edges[count1].next=head[u]; head[u]=count1++; } bool dfs(int u,int d) { if(vis[u]) return false; vis[u]=1; dis[u]=d; parent[u]=u; for(int i=head[u]; i!=-1; i=edges[i].next) { int v=edges[i].v; if(vis[v]) { int p=getparent(v); ans[edges[i].ran]=dis[u]+dis[v]-2*dis[p]; } } for(int i=0; i<vec[u].size(); i++) { if(dfs(vec[u][i].first,d+vec[u][i].second)) parent[vec[u][i].first]=u; } return true; } int main() { cin>>n>>m; memset(head,-1,sizeof head); memset(vis,0,sizeof vis); for(int i=0; i<m; i++) { int a,b,c; char r; scanf("%d%d%d",&a,&b,&c); cin>>r; add(a,b,c); add(b,a,c); } int k; cin>>k; for(int i=0; i<k; i++) { int a,b; cin>>a>>b; addedge(a,b,i); addedge(b,a,i); } dfs(1,0); for(int i=0; i<k; i++) cout<<ans[i]<<"\n"; return 0; }
相关文章推荐
- c++在vs2012中链接mysql操作
- 获取中国当前(上海时区)时间字符串
- 接口和继承
- C++模板:函数模板和模板函数 .
- 简单Dream-tnsping 报错:TNS-12533: TNS:illegal ADDRESS parameters
- Linux(centOS 6.X)下sqlplus无法使用删除和历史命令BUG解决方法
- Flow之一个新的Javascript静态类型检查器
- 自己的服务器通过微信公众号Token验证测试的代码(Python版)
- Node.js 事件循环
- 基于php常用正则表达整理(下)
- Android开发_关于如何屏蔽Home键
- 返回字符串最后一个单词的长度
- Jeecg_3.6新版本功能专题讲解 - 公开课(自定义表单、数据权限)
- 集合遍历方法
- ListView加载不同布局
- stuts2显示多行多列
- css3 新属性
- matlab获取标量
- Ramfs与Tmpfs的使用
- 微信公众帐号自定义菜单创建的python脚本