zoukankan      html  css  js  c++  java
  • 树上三点间距离

    P4281 [AHOI2008]紧急集合 / 聚会

    这道题很卡常

    但用一些优化 可过

    问题

    求一点到 三个不同点的距离最小

    输出这个点 和这个距离

    #define sum(a,b,c) (depth[a] + depth[b] + depth[c])
    t,ab = lca(a,b),ac = lca(a,c),bc = lca(b,c);
    if(ab == ac) t = bc;
    if(ab == bc) t = ac;
    if(ac == bc) t = ab;
    printf("%d %d
    ",t,sum(a,b,c) - sum(ab,ac,bc));
    

    感性理解下

    倍增的一些优化

    for(reg i = 1;i <= n;i++) 
            lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
            
    inline int lca(int a,int b)
    {
    	if(depth[a] < depth[b]) swap(a,b);
    	while(depth[a] > depth[b]) a = fa[a][lg[depth[a] - depth[b]] - 1];
    	if(a == b) return a;
    	for(reg i = lg[depth[a]];i >= 0;i--)
    		if(fa[a][i] != fa[b][i])
    			a = fa[a][i],b = fa[b][i];
    	return fa[a][0];
    }
    

    总结

    • 少函数,非递归函数用宏

    • (lca),提前处理(log)

    • register int

    • 变量名尽量小写,短

    (Code)

    
    #include <cstdio>
    #include <vector>
    #include <iostream>
    using namespace std;
    #define reg register int
    const int MAXN = 5e5 + 10;
    int cnt,fa[MAXN][30],lg[MAXN],head[MAXN],depth[MAXN],n,m;
    bool vis[MAXN];
    struct node
    {
    	int v,next;
    }edge[MAXN << 1];
    template<typename T>
    inline T Read(T Type)
    {
    	T x = 0;
    	bool f = 0;
    	char a = getchar();
    	while(!isdigit(a)) {if(a == '-') f = 1;a = getchar();}
    	while(isdigit(a)) x = (x << 1) + (x << 3) + a - '0',a = getchar();
    	if(f) x *= -1;
    	return x;
    }
    inline void addedge(int u,int v)
    {
    	edge[++cnt].v = v;
    	edge[cnt].next = head[u];
    	head[u] = cnt;
    }
    inline void prepare(int x)
    {
    	vis[x] = 1;
    	for(reg i = head[x];i;i = edge[i].next)
    	{
    		int v = edge[i].v;
    		if(vis[v]) continue;
    		fa[v][0] = x;
    		depth[v] = depth[x] + 1;
    		prepare(v);
    	}
    }
    inline int lca(int a,int b)
    {
    	if(depth[a] < depth[b]) swap(a,b);
    	while(depth[a] > depth[b]) a = fa[a][lg[depth[a] - depth[b]] - 1];
    	if(a == b) return a;
    	for(reg i = lg[depth[a]];i >= 0;i--)
    		if(fa[a][i] != fa[b][i])
    			a = fa[a][i],b = fa[b][i];
    	return fa[a][0];
    }
    #define sum(a,b,c) (depth[a] + depth[b] + depth[c])
    int main()
    {
    	n = Read(1),m = Read(1);
    	for(reg i = 1;i < n;i++)
    	{
    		int u,v;
    		scanf("%d%d",&u,&v);
    		addedge(u,v),addedge(v,u);
    	}
    	fa[1][0] = 1;
    	for(reg i = 1;i <= n;i++) 
            lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    	prepare(1);
    	for(reg i = 1;i <= lg[n];i++)
    		for(reg j = 1;j <= n;j++)
    			fa[j][i] = fa[fa[j][i - 1]][i - 1];
    	int t,a,b,c,ab,ac,bc;
    	for(reg i = 1;i <= m;i++)
    	{
    		a = Read(1),b = Read(1),c = Read(1),t,ab = lca(a,b),ac = lca(a,c),bc = lca(b,c);
    		if(ab == ac) t = bc;
    		if(ab == bc) t = ac;
    		if(ac == bc) t = ab;
    		printf("%d %d
    ",t,sum(a,b,c) - sum(ab,ac,bc));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    mac下卸载mysql
    mac安装MySQL笔记
    mac安装python3.7.0
    web自动化测试之8大元素定位方法
    postman的下载和使用
    说说性能测试
    jmeter动态修改线程组参数
    服务器性能监控
    性能测试分配堆内存
    nmon分析工具的使用
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/11783159.html
Copyright © 2011-2022 走看看