zoukankan      html  css  js  c++  java
  • luoguP4281

    这个题目有好多人倍增求LCA会被卡成80分(包括第一次提交的我,然后,我在万神的教导下,使用了优化版的倍增,直接水过去了.....跑得还挺快,最大点700ms(没有优化前1500ms),好吧其实还是卡过去的,用了快读快写,不过这里优化的倍增求LCA还是值得拿起小本子记录一下的哈哈)

    Code:

    #include <bits/stdc++.h>
    using namespace std;
    int m = 0,n,Q;
    int head[500005];
    struct Edge{
    	int next,to;
    }edge[1000005];
    int deep[500005],parent[500005][21];
    
    void DFS(int x,int from);
    void add(int from,int to);
    int LCA(int x,int y);
    inline int read();
    int deal(int A,int B,int C);
    int getlen(int A,int B);
    inline void write(int x)
    {
    	if(x == 0)putchar('0');
    	char b[30];
    	int R = 0;
    	while(x)
    		R++,b[R] = x%10 + '0',x/=10;
    	for(int i = R ; i >= 1 ; i --)
    		putchar(b[i]);
    }
    int main()
    {
    	n = read() , Q = read();
    	for(int i = 1 ; i <= n - 1; i ++)
    	{
    		int u,v;
    		u = read() , v = read();
    		add(u,v),add(v,u);
    	}
    	DFS(1,0);
    	while(Q)
    	{
    		int A,B,C;
    		A = read() , B = read() , C = read();
    		write(deal(A,B,C)),putchar('
    ');
    		Q --;
    	}
    	return 0;
    }
    
    int getlen(int A,int B)//获取AB之间的路径长度
    {
    	return deep[A] + deep[B] - 2*deep[LCA(A,B)];
    }
    
    int deal(int A,int B,int C)
    {
    	int AB = LCA(A,B) , AC = LCA(A,C) , BC = LCA(B,C);
    	int ansAB,ansAC,ansBC;
    	ansAB = getlen(A,AB) + getlen(B,AB) + getlen(C,AB);
    	ansAC = getlen(A,AC) + getlen(B,AC) + getlen(C,AC);
    	ansBC = getlen(A,BC) + getlen(B,BC) + getlen(C,BC);
    	if(ansAB <= ansBC && ansAB <= ansAC)
    	{
    		write(AB);putchar(' ');
    		return ansAB;
    	}
    	if(ansAC <= ansBC && ansAC <= ansAB)
    	{
    		write(AC);putchar(' ');
    		return ansAC;
    	}
    	if(ansBC <= ansAB && ansBC <= ansAC)
    	{
    		write(BC);putchar(' ');
    		return ansBC;
    	}
    }
    
    int LCA(int x,int y)
    {
    	if(deep[x] > deep[y])swap(x,y);
    	for(int i = log2(deep[y] - deep[x]) + 1 ; i >= 0 ; i --)
    		if(deep[parent[y][i]] >= deep[x])
    			y = parent[y][i];
    	if(x == y)return x;
    	for(int i = log2(deep[x])+1 ; i >= 0 ; i --)
    		if(parent[x][i] != parent[y][i])
    		x = parent[x][i] , y = parent[y][i];
    	return parent[x][0];
    }
    
    void DFS(int x,int from)
    {
    	deep[x] = deep[from] + 1;
    	parent[x][0] = from;
    	for(int i = 1 ; i <= 20 ; i ++)
    		parent[x][i] = parent[parent[x][i-1]][i-1];
    	for(int i = head[x] ; i ; i = edge[i].next)
    	{
    		int to = edge[i].to;
    		if(! deep[to])DFS(to , x);
    	}
    	return ;
    }
    
    void add(int from,int to)
    {
    	m++;
    	edge[m].to = to;
    	edge[m].next = head[from];
    	head[from] = m;
    }
    
    inline int read()
    {
    	int x = 0,flag = 1;
    	char ch = getchar();
    	for( ; ch > '9' || ch < '0' ; ch = getchar())if(ch == '-')flag = -1;
    	for( ; ch >= '0' && ch <= '9' ; ch = getchar())x = (x << 3) + (x << 1) + ch - '0';
    	return x * flag;
    }
    
  • 相关阅读:
    移动端(手机端)页面自适应解决方案1(rem布局)---750设计稿
    ionic4之ion-sliders
    ionic4 新建
    Object的多种方法
    angular的Hash 模式和 HTML 5 模式
    关于滚动条
    前端笔记(1-20)
    百度图片网址
    ImageLoader_显示图片
    viewpager_轮播
  • 原文地址:https://www.cnblogs.com/MYCui/p/13869871.html
Copyright © 2011-2022 走看看