HDU2586 How far away ?(LCA在线RMQ-ST)
来源:互联网 发布:薛之谦 做作 知乎 编辑:程序博客网 时间:2024/05/22 13:48
题目点我点我点我
题目大意:求两个节点间最短距离。
解题思路:LCA(最近公共祖先),dis[i]表示从根节点到节点i的距离,所以要求节点u和节点v之间的距离则有dis[u]+dis[v]-2*dis[LCA(u,v)]。此处我是基于RMQ-ST写的。
第一次写这种题,过了样例却wa了一整页,度娘来的基本都是Tarjan算法的,没有多少是用RMQ写的,极其心累,调了一上午bug,才发现要先dfs再ST……ORZ。另在讨论区发现一组挺好的数据:
15 31 2 1001 3 2002 4 3002 5 1004 53 42 3结果400600300
/* ***********************************************┆ ┏┓ ┏┓ ┆┆┏┛┻━━━┛┻┓ ┆┆┃ ┃ ┆┆┃ ━ ┃ ┆┆┃ ┳┛ ┗┳ ┃ ┆┆┃ ┃ ┆┆┃ ┻ ┃ ┆┆┗━┓ 马 ┏━┛ ┆┆ ┃ 勒 ┃ ┆ ┆ ┃ 戈 ┗━━━┓ ┆┆ ┃ 壁 ┣┓┆┆ ┃ 的草泥马 ┏┛┆┆ ┗┓┓┏━┳┓┏┛ ┆┆ ┃┫┫ ┃┫┫ ┆┆ ┗┻┛ ┗┻┛ ┆************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;#define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++)#define per(i,a,b) for (int i=(b),_ed=(a);i>=_ed;i--)#define pb push_back#define mp make_pairconst int inf_int = 2e9;const long long inf_ll = 2e18;#define inf_add 0x3f3f3f3f#define mod 1000000007#define LL long long#define ULL unsigned long long#define MS0(X) memset((X), 0, sizeof((X)))#define SelfType intSelfType Gcd(SelfType p,SelfType q){return q==0?p:Gcd(q,p%q);}SelfType Pow(SelfType p,SelfType q){SelfType ans=1;while(q){if(q&1)ans=ans*p;p=p*p;q>>=1;}return ans;}#define Sd(X) int (X); scanf("%d", &X)#define Sdd(X, Y) int X, Y; scanf("%d%d", &X, &Y)#define Sddd(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}//#pragma comment(linker, "/STACK:102400000,102400000")const int N = 40010;int dp[2*N][20],dis[N];struct edge{ int to,next,w;}e[2*N];int last[N],cnt;void addedge(int u,int v,int w){ e[++cnt] = edge{v,last[u],w};last[u] = cnt; e[++cnt] = edge{u,last[v],w};last[v] = cnt;}int vs[2*N]; //DFS访问的顺序int dep[2*N]; //节点的深度int ver[N]; //各个顶点在vs中首次出现的下标void dfs(int v,int p,int d,int &k){ ver[v] = k; vs[k] = v; dep[k++] = d; for(int i=last[v];i!=-1;i=e[i].next) { if(e[i].to!=p) { dis[e[i].to]=dis[v]+e[i].w; dfs(e[i].to,v,d+1,k); vs[k] = v; dep[k++] = d; } }}void st(int n){ for(int i=0;i<=n;i++)dp[i][0]=i; for(int j=1;(1<<j)<=n;j++) { for(int i=1;i+(1<<j)-1<n;i++) { int a = dp[i][j-1] , b = dp[i+(1<<(j-1))][j-1]; dp[i][j] = dep[a]<dep[b]?a:b; } }}int rmq(int l,int r){ int k = (int)(log(1.0*(r-l+1))/log(2.0)); int a = dp[l][k]; int b = dp[r-(1<<k)+1][k]; return dep[a]<dep[b]?a:b;}int LCA(int u,int v){ int x = ver[u], y = ver[v]; if(x>y)swap(x,y); int res = rmq(x,y); return vs[res];}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);ios::sync_with_stdio(0);cin.tie(0); Sd(cas); while(cas--) { Sdd(n,q); cnt = 0; memset(last,-1,sizeof last); for(int i=1;i<n;i++) { Sddd(u,v,w); addedge(u,v,w); } for(int i=0;i<=n;i++) dis[i] = -1; dis[1] = 0; int k = 0; dfs(1,-1,0,k); st(2*n-1); while(q--) { Sdd(l,r); printf("%d\n",dis[l]+dis[r]-2*dis[LCA(l,r)]); } }return 0;}
0 0
- HDU2586 How far away ?(LCA在线RMQ-ST)
- hdu2586 How far away ?(LCA->RMQ)
- HDU2586 How far away?(树链剖分求LCA)
- hdu2586 How far away? LCA
- hdu 2586 How far away ?(lca-在线ST)
- HDU2586 How far away ?(LCA离线算法)
- hdu2586-LCA(tarjan法)-How far away ?
- HDU2586 How far away ?(LCA,Tarjan算法)
- hdu2586 how far away?(lca求距离)
- [LCA Problem] hdu2586 How far away ?
- HDU2586 How far away ?(LCA模板题)
- 离线LCA hdu2586 How far away ?
- 倍增法LCA hdu2586 How far away ?
- hdu2586 How far away ? (LCA离线)
- hdu2586 How far away ?--tarjan & LCA
- hdu2586 How far away ? 【图论-Tarjan-Lca】
- Tarjan-LCA HDU2586 How far away ?
- 【LCA】HDU2586[How far away?]题解
- 《编程之法》1.4字符串转换成整数
- PHP 表单 - 验证名称、邮件和URL
- 慕课网实战—《用组件方式开发 Web App全站 》笔记五-折线图组件开发
- JavaScript的事件监听与捕获和冒泡
- Linux进程间通讯(IPC)------匿名管道
- HDU2586 How far away ?(LCA在线RMQ-ST)
- php路由相关(url重定向)
- ES6箭头函数和它的作用域
- 数据库索引
- C#文件读写常用接口
- visio 2010 激活方法
- Re: Programming in C with Bluetooth Sockets
- IDEA快捷键对比Eclipse
- struts2环境搭建