hdu2586 LCA应用 求树的任意两节点的距离
来源:互联网 发布:如何使用炒股软件 编辑:程序博客网 时间:2024/06/05 17:26
http://acm.hdu.edu.cn/showproblem.php?pid=2586
题意:给出一棵树,求两节点的的距离
解题思路:
直接BFS超时,所以要使用LCA(离线tarjan算法)。
例如求x,y节点的距离,那么先求出x,y的lca是u节点,那么结果就是dis[x]+dis[y]-2*dis[u]
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<iostream>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#include<bitset>#define ll __int64using namespace std;#define N 40005vector<int>tree[N];//图的邻接表vector<pair<int,int> >Q[N];//询问int ans[N];//保存每个询问的结果int f[N];int dis[N];//dis[i]是root到i节点的距离int find(int x)//找父根节点{if(f[x]!=x){f[x]=find(f[x]);}return f[x];}void mark(int a,int b){ f[find(b)] = find(a);}void LCA(int u){ f[u]=u;for(int i=0; i<tree[u].size(); i++) //未visit子节点 { LCA(tree[u][i]); mark(u, tree[u][i]);//将子节点并到父结点的集合中 }for(int i=0; i<Q[u].size(); i++)//求当前节点与有关的节点的最近公共祖先{if(f[Q[u][i].first]!=-1)//如果另一个节点也已处理过{ ans[Q[u][i].second]=find(Q[u][i].first);}}}void callLCA(int root){ LCA(root);}vector<pair<int,int> >V[N];//记录无向图void init(int n){ memset(f,-1,sizeof(f)); memset(ans,-1,sizeof(ans)); for(int i=0;i<=n;i++) { tree[i].clear(); Q[i].clear(); V[i].clear(); }}int flag[N];int BFS_getPoint()//对无向图进行BFS,从而获取树的一个端点{ int start=1; memset(flag,0,sizeof(flag)); queue<int>QUE; QUE.push(start); int lastOne=-1; while(!QUE.empty()) { int now=QUE.front(); QUE.pop(); lastOne=now; flag[now]=1; for(int i=0;i<V[now].size();i++) { if(flag[V[now][i].first]==0) { QUE.push(V[now][i].first); } } } return lastOne;}void BFS_calDis(int root)//记录root节点到所有节点的距离,并且初始化树{ memset(dis,0,sizeof(dis)); memset(flag,0,sizeof(flag)); queue<pair<int,int> >QUE; pair<int,int>p,q; p=make_pair(root,0); QUE.push(p); while(!QUE.empty()) { q=QUE.front(); QUE.pop(); dis[q.first]=q.second; flag[q.first]=1; for(int i=0;i<V[q.first].size();i++) { if(flag[V[q.first][i].first]==0) { p=make_pair(V[q.first][i].first,q.second+V[q.first][i].second); QUE.push(p); tree[q.first].push_back(p.first); } } }}int main(){int i,j,k;int t,n,m;scanf("%d",&t);while(t--){ int q; scanf("%d%d",&n,&q); init(n); for(i=1;i<=n-1;i++)//记录无向图 { int from,to,len; scanf("%d%d%d",&from,&to,&len); pair<int,int>p; p=make_pair(to,len); V[from].push_back(p); p=make_pair(from,len); V[to].push_back(p); } int get=BFS_getPoint();//找无向图形成的树的根节点 BFS_calDis(get);//形成树的有向图(父结点->子节点) pair<int,int>p; vector<pair<int,int> >Record; Record.clear(); for(i=1;i<=q;i++) { int from,to; scanf("%d%d",&from,&to); p=make_pair(from,to); Record.push_back(p); p=make_pair(to,i); Q[from].push_back(p); p=make_pair(from,i); Q[to].push_back(p); } callLCA(get); for(i=1;i<=q;i++) { if(ans[i]==-1) {printf("not connect");} else { int len=dis[Record[i-1].first]+dis[Record[i-1].second]-2*dis[ans[i]]; printf("%d\n",len); } }}}/*input:13 21 2 103 1 151 22 3output:1025*/
0 0
- hdu2586 LCA应用 求树的任意两节点的距离
- hdu2874 LCA求森林中任意两节点的距离
- poj 1986 LCA 求树上任意两节点距离
- LCA二叉树任意两节点的共同祖先
- 计算二叉树的任意两节点的最远距离。
- 二叉树的任意两节点间的最大距离
- 二叉树中任意两节点的距离
- 求二叉树中任意两结点的距离
- 求二叉树中任意两结点的距离
- 求二叉树两节点的最远距离
- LCA问题:求二叉树中任意两个节点的最近公共祖先
- hdu2586 how far away?(lca求距离)
- 求一个二叉树中任意两个节点间的最大距离
- 【每日面试题】求一个二叉树中任意两个节点间的最大距离
- 求一个二叉树中任意两个节点间的最大距离
- 求一个二叉树中任意两个节点间的最大距离
- poj 2763 求任意树的2个节点之间距离和修改2点之间的距离
- 第十一题:求二叉树任意两结点的最大距离
- hdu-2554-Kth number 划分树模板
- highcharts参数详解文档
- 个人感觉程序员应有的素质
- java.lang.StackOverflowError
- Eclipse添加DTD文件实现xml的自动提示功能
- hdu2586 LCA应用 求树的任意两节点的距离
- 获取当前图纸的名称
- hbase集群部署
- 工作杂记(一)
- VS2010 Silverlight学习——启动xaml方式
- lua之数据类型
- 计算机英语之分布式管理环境
- leetcode:【Max Points on a Line】
- android流量统计的小结