cdoj 92 Journey lca
来源:互联网 发布:双色球出号绝密算法 编辑:程序博客网 时间:2024/06/14 11:50
题意:给定一棵树, 然后加一条边, 有若干询问, 问你每一个询问(u,v), 加了这条边后可以从u到v节省多少距离。
思路: 一共三种情况, 1, 原路
2,u - x - y - v
3,u - y - x - v
#include <bits/stdc++.h>using namespace std;const int MAXN = 100010;struct node{int to, w, next;}edge[MAXN*2];int tot,head[MAXN];void init(){tot = 0;memset(head, -1, sizeof(head));}void add_edge(int u, int v, int w){edge[tot].to = v;edge[tot].w = w;edge[tot].next = head[u];head[u] = tot++;}//LCA部分int rmq[2*MAXN];//rmq数组,就是欧拉序列对应的深度序列struct ST{ int mm[2*MAXN]; int dp[2*MAXN][20];//最小值对应的下标 void init(int n) { mm[0] = -1; for(int i = 1;i <= n;i++) { mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; dp[i][0] = i; } for(int j = 1; j <= mm[n];j++) for(int i = 1; i + (1<<j) - 1 <= n; i++) dp[i][j] = rmq[dp[i][j-1]] < rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]; } int query(int a,int b)//查询[a,b]之间最小值的下标 { if(a > b)swap(a,b); int k = mm[b-a+1]; return rmq[dp[a][k]] <= rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k]; }};int F[MAXN*2];//欧拉序列,就是dfs遍历的顺序,长度为2*n-1,下标从1开始int P[MAXN];//P[i]表示点i在F中第一次出现的位置int cnt;int dis[MAXN]; ST st;void dfs(int u,int pre,int dep, int d){dis[u] = d; F[++cnt] = u; rmq[cnt] = dep; P[u] = cnt; for(int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].to; if(v == pre)continue; dfs(v,u,dep+1, edge[i].w+d); F[++cnt] = u; rmq[cnt] = dep; }}void LCA_init(int root,int node_num)//查询LCA前的初始化{ cnt = 0; dfs(root,root,0, 0); st.init(2*node_num-1);}int query_lca(int u,int v)//查询u,v的lca编号{ return F[st.query(P[u],P[v])];}int calc(int u, int v){int LCA = query_lca(u, v);return dis[u] + dis[v] - 2*dis[LCA];}int main(){int T;cin>>T;int icase = 0;while(T--){init();printf("Case #%d:\n", ++icase);int n,q;scanf("%d %d", &n, &q);for(int i=1; i<n; i++){int u,v,w;scanf("%d %d %d", &u, &v, &w);add_edge(u, v, w), add_edge(v, u, w);}LCA_init(1, n);int u,v,w;int lca = query_lca(u, v);scanf("%d %d %d", &u, &v, &w);while(q--){int x,y;scanf("%d %d", &x, &y);int sum1 = calc(x, y);int sum2 = calc(x, u) + w + calc(y, v);int sum3 = calc(y, u) + w + calc(x, v);if(sum2 >= sum1 && sum3>=sum1) printf("0\n");else printf("%d\n", sum1 - min(sum2, sum3));}}return 0;}
0 0
- cdoj 92 Journey lca
- UESTC 92 Journey(LCA)
- UESTC 92 Journey (LCA)
- UESTC 92 Journey(LCA)
- UESTC 92 Journey(LCA 裸题)
- UESTC - 92 Journey(LCA)1012四川省赛
- UESTC 92 Journey(LCA或树剖)
- BNU 24258 Journey (LCA)
- Journey
- bnuoj 24258 Journey(lca倍增法 弱校联萌十一大决战之背水一战J)
- UESTC 92 LCA
- LCA
- LCA
- lca
- LCA
- LCA
- lca
- LCA
- IT从业不息,博客不止
- java 内部类分为成员内部类,局部内部类,匿名内部类,
- Django中更新多个对象数据与删除对象的方法
- CodeForces 1A Theatre Square(math)——Codeforces Beta Round #1
- [LeetCode]Set Matrix Zeroes
- cdoj 92 Journey lca
- Redis核心解读–集群管理工具(Redis-sentinel)
- 利用git把项目源码下载到本地,然后本地做gem打包,进行gem intall的流程
- Android SQLiteDatabase的使用模板
- MSSQLSERVER服务无法启动的解决方案
- HDU 5128 The E-pang Palace (排序+暴力)2014 ICPC 广州站现场赛
- 数组的用法
- Mac OS X 10.10 装gdb
- 【单机版,以两个文件为例】K-Shingle+最小Hash签名+LSH算法+LSH族....Java代码