zoukankan      html  css  js  c++  java
  • BZOJ 1787 紧急集合

    1787: [Ahoi2008]Meet 紧急集合

    Time Limit: 20 Sec  Memory Limit: 162 MB
    Submit: 1220  Solved: 500
    [Submit][Status]

    Description

    Input

    Output

    Sample Input

    6 4
    1 2
    2 3
    2 4
    4 5
    5 6
    4 5 6
    6 3 1
    2 4 4
    6 6 6

    Sample Output

     
    5 2
    2 5
    4 1
    6 0

    HINT

    ——分割线——

    卧槽、、感觉好不好QAQ我写的程序最近总是评测CE!这、、让我怎么去考NOIP!好吧,这次是因为用了IO库里的一个Swap函数,可是明明在IO库里啊、、、为什么会CE、、看来我以后不能提前写好多好多头文件了、、、、

    言归正传,这题就是练一下LCA,卧槽,这次我感受到了数组地址冲突导致的莫名其妙数据不正常问题,调了好久才发现是地址冲突QAQ!LCA感觉还是不是很熟练,找时间再写一题,这道题吧,很容易得到,他们的集合点就是三个点两两的LCA之一,都算出来比一下距离就好啦~

    代码:

    /*Author:WNJXYK*/
    #include<cstdio>
    using namespace std;
    
    #define LL long long
    
    const int Maxn=500000;
    int n,m;
    struct Node{
    	int u;
    	int nxt;
    	Node(){}
    	Node(int a,int b){
    		u=a;
    		nxt=b;
    	}
    };
    int nume=0;
    Node link[2*Maxn+10];
    int links[Maxn+10];
    int visited[Maxn+10];
    int lca[Maxn+10][20];
    int depth[Maxn+10];
    int Mlca=20;
    
    int dfs(int x,int deep){
    	depth[x]=deep;
    	visited[x]=true;
    	for(int i=1;i<Mlca;i++){
    		lca[x][i]=lca[lca[x][i-1]][i-1];
    	}
    	for (int i=links[x];i;i=link[i].nxt){
    		int point=link[i].u;
    		if (!visited[point]){
    			lca[point][0]=x;
    			dfs(point,deep+1);
    		}
    	}
    }
    
    inline void swin(int &x,int step){
    	for (int i=0;step>0;i++){
    		if (step%2==1) x=lca[x][i];
    		step/=2;
    	}
    }
    
    inline void swap(int &x,int &y){
    	x=x+y;
    	y=x-y;
    	x=x-y;
    }
    
    inline int LCA(int x,int y){
    	if (depth[x]>depth[y]) swap(x,y);
    	swin(y,depth[y]-depth[x]);
    	if (x==y) return x;
    	for (int i=0;;){
    		for(i=0;lca[x][i]!=lca[y][i];i++);
    		if (i==0) return lca[x][i];
    		x=lca[x][i-1];
    		y=lca[y][i-1];
    	}
    	return -1;
    }
    
    inline void addEdge(int x,int y){
    	link[++nume]=Node(y,links[x]);
    	links[x]=nume;
    }
    
    inline int dist(int x,int y){
    	int l=LCA(x,y);
    	return depth[x]+depth[y]-2*depth[l];
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<n;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		addEdge(x,y);
    		addEdge(y,x);
    	}
    	lca[1][0]=1;
    	dfs(1,1);
    	for (int i=1;i<=m;i++){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		int lx,ly,lz;
    		lx=LCA(x,y);
    		ly=LCA(y,z);
    		lz=LCA(z,x);
    		//cout<<lx<<" "<<ly<<" "<<lz<<" "<<endl;
    		int l=lx^ly^lz;
    		int ans=dist(l,x)+dist(l,y)+dist(l,z);
    		printf("%d %d
    ",l,ans);
    	}
    	return 0;
    }
    




  • 相关阅读:
    (考研)散列表和hashcode和hashmap
    java基本数据类型和引用类型
    Java 中的语法糖(7/15整个周六上午总结)
    数据库第一天-数据库索引
    MonoBehaviour生命周期
    Unity基础知识
    SQLite3笔记
    cocos_js写文件
    UGUI_屏幕适配
    KMS算法
  • 原文地址:https://www.cnblogs.com/WNJXYK/p/4063936.html
Copyright © 2011-2022 走看看