poj 1968 Distance Queries LCA Tarjan 离线算法
来源:互联网 发布:淘宝总部投诉电话 编辑:程序博客网 时间:2024/05/25 12:20
链接:http://poj.org/problem?id=1986
算法概述:所谓离线,就是把所有要求公共祖先的结点对用邻接表存起来,输入完毕后一起计算。
算法实现不困难,就是并查集和DFS。
从根开始遍历,遍历到新的结点时将该点记录为根(H[u]=u),建立以这个点为根的集合。对这个集合的每个子树进行搜索,即将子树内部的存在的所有LCA询问解决。当搜索到LCA的一个点,另外一个点被询问过了,最近公共祖先就是另外一个点此时的根。如果有子树中LCA没有解决,则其LCA询问不在这个根的子树内,将该子树所有点的根记录为u。由于是递归实现,则保证最先找到的最近的祖先。看代码显而易见。
题意:给N个农场,给出M对农场之间的距离。计算K对农场的距离。
思路:是一道标准的模板题。数据量到不能用最短路算,所以用LCA。记录从根到每个点之间的深度,答案就是ans[i]=d[query[i].v]+d[u]-2*d[findset(query[i].v)]。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<map>#include<queue>#include<stack>#include<vector>#include<ctype.h>#include<algorithm>#include<string>#define PI acos(-1.0)#define maxn 100005#define INF 1<<25#define MAX 0x7ffffffftypedef long long ll;using namespace std;struct Edge{ int v,w; int next;} edge[maxn],query[maxn];int ans[maxn],point[maxn],head[maxn],d[maxn],aa[maxn],H[maxn],vv[maxn],tot,tt;;int e_top,q_top;int init(){ e_top=q_top=0; memset(vv,0,sizeof(vv)); memset(head,-1,sizeof(head)); memset(aa,0,sizeof(aa)); memset(point,-1,sizeof(point)); memset(ans,0,sizeof(ans)); memset(d,0,sizeof(d)); memset(H,0,sizeof(H));}int add_edge(int u,int v,int w){ edge[e_top].v=v; edge[e_top].w=w; edge[e_top].next=head[u]; head[u]=e_top++; edge[e_top].v=u; edge[e_top].w=w; edge[e_top].next=head[v]; head[v]=e_top++;}int add_query(int u,int v){ query[q_top].v=v; query[q_top].next=point[u]; point[u]=q_top++; query[q_top].v=u; query[q_top].next=point[v]; point[v]=q_top++;}int findset(int x){ return x==H[x]?x:H[x]=findset(H[x]);}int dfs(int u,int w){ d[u]=w,H[u]=u; vv[u]=1; for(int i=head[u]; i!=-1; i=edge[i].next) { if(!vv[edge[i].v]) { dfs(edge[i].v,w+edge[i].w); H[edge[i].v]=u; } } for(int i=point[u];i!=-1;i=query[i].next) { if(vv[query[i].v]) ans[i]=d[query[i].v]+d[u]-2*d[findset(query[i].v)]; }}int main(){ scanf("%d%d",&tot,&tt); init(); for(int i=0;i<tt;i++) { int x,y,z; char ss[2]; scanf("%d%d%d%s",&x,&y,&z,ss); add_edge(x,y,z); } scanf("%d",&tt); for(int i=0;i<tt;i++) { int x,y; scanf("%d%d",&x,&y); add_query(x,y); } dfs(1,0); for(int i=0;i<tt*2;i+=2) { if(ans[i]==0) printf("%d\n",ans[i+1]); else printf("%d\n",ans[i]); }}
0 0
- poj 1968 Distance Queries LCA Tarjan 离线算法
- POJ 1986 Distance Queries(LCA Tarjan离线算法)
- poj 1986 Distance Queries(LCA离线Tarjan算法)
- POJ 1986 Distance Queries LCA离线算法tarjan
- POJ 1986 Distance Queries(离线tarjan-LCA)
- POJ 1986 Distance Queries (Tarjan-LCA算法)(带权值)
- POJ---1986-Distance Queries(LCA-Tarjan)
- POJ 1986Distance Queries tarjan求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—tarjan>
- poj1986 Distance Queries 离线LCA
- POJ1986 Distance Queries (tarjan算法LCA 模板题)
- POJ1986 Distance Queries【最近公共祖先】【Tarjan-LCA算法】
- POJ 题目1986 Distance Queries(LCA 离线)
- POJ 1986 Distance Queries(LCA在线和离线)
- Afaria 服务器虚拟机环境要求
- WPF/Silverlight Template使用及总结
- Android键盘输出增加按键码
- Mysql使用存储过程和Event事件定期删除数据
- 【Error】Call requires API level 3 (current min is 1)解
- poj 1968 Distance Queries LCA Tarjan 离线算法
- 快速学习一门编程语言
- 项目经理如何分配任务
- LaTeX的color的package中预定义了哪些颜色名称?
- Android 资源文件中@、@android:type、@*、?、@+含义和区别
- Mac os sshd config
- Java开发十大必备网站
- jstl fmt
- UVa 10902 / POJ 2653 Pick-up Sticks (线段与线段相交)