zoukankan      html  css  js  c++  java
  • LOJ #10134. 「一本通 4.4 练习 1」Dis

    做这道题需要知道一个性质:树上 (x,y) 两点的距离为 (dis(x)+dis(y)-2dis(LCA(x,y))),其中 (dis(i)) 表示 (i) 点离根节点的距离,(LCA(i,j)) 表示 (i,j) 两点的 LCA(最近公共祖先)。

    然后就直接水过去了。在预处理 fa 数组时直接将 dis 数组带着预处理一遍就 A 掉了(这什么垃圾题解)。

    Code:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxN=10005,logn=15;
    struct Edge {int to,val,nxt;}edge[maxN<<1];
    int n,m,tot,fa[maxN][logn],dep[maxN],hd[maxN],dis[maxN];
    void add(int,int,int),dfs(int,int);
    int LCA(int,int),query(int,int);
    int main() {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<n;i++) {
    		int x,y,v;scanf("%d%d%d",&x,&y,&v);
    		add(x,y,v);
    		add(y,x,v);
    	}
    	dfs(1,1);
    	for (;m;m--) {
    		int x,y;scanf("%d%d",&x,&y);
    		printf("%d
    ",query(x,y));
    	}
    	return 0;
    }
    void add(int x,int y,int v) {
    	edge[++tot].to=y;
    	edge[tot].val=v;
    	edge[tot].nxt=hd[x];
    	hd[x]=tot;
    }
    void dfs(int u,int d) {
    	dep[u]=d;
    	for (int i=hd[u];i;i=edge[i].nxt) {
    		int o=edge[i].to;
    		if (dep[o]) continue;
    		fa[o][0]=u;
    		for (int j=1;fa[o][j-1];j++)
    			fa[o][j]=fa[fa[o][j-1]][j-1];
    		dis[o]=dis[u]+edge[i].val;
    		dfs(o,d+1);
    	}
    }
    int LCA(int u,int v) {
    	if (dep[u]<dep[v]) swap(u,v);
    	for (int i=logn;~i;i--)
    		if (dep[u]-(1<<i)>=dep[v]) u=fa[u][i];
    	if (u==v) return u;
    	for (int i=logn-1;~i;i--)
    		if (fa[u][i]!=fa[v][i]) {
    			u=fa[u][i];
    			v=fa[v][i];
    		}
    	return fa[u][0];	
    }
    int query(int u,int v) {return dis[u]+dis[v]-(dis[LCA(u,v)]<<1);}
    
  • 相关阅读:
    Spring
    linux下jdk多版本管理
    linux集群管理
    python多任务处理
    Web框架的引入
    Git命令大全
    Git远程仓库--GitHub
    基于python实现简单web服务器
    python文件读写方式
    几句话搞懂URI、URL、URN之间的关系
  • 原文地址:https://www.cnblogs.com/Xray-luogu/p/12634315.html
Copyright © 2011-2022 走看看