zoukankan      html  css  js  c++  java
  • codeforces #629 E-Tree Queries

    • 题意:给一个以1为根节点树,m次询问,每次选k个节点,问是否存在一个节点u,在1~u的路径上所有这k个点到这条路径的距离都小于等于1。
    • 题解:d[]记录每个点到根节点的距离,这个u一定是k个点中d[]最大的那个点。然后判断其他点满足条件吗。判断方法就是看d[a[i]] - d[lca(u, a[i])] 是否都小于 1。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int N = 2e5 + 105;
    const int mod = 1e9 + 7;
    const double Pi = 3.1415926;
    const ll INF = 0x3f3f3f3f;
    
    int n, m, t, k, flag = 0;
    int head[N], cnt = 0;
    int d[N], a[N], f[N][20];
    
    
    struct node{
    	int to;
    	int nxt;
    }edge[4 * N];
    queue<int>q;
    
    inline void add(int x, int y){
    	edge[cnt].to = y;
    	edge[cnt].nxt = head[x];
    	head[x] = cnt ++;
    }
    
    void bfs(){
    	q.push(1);
    	d[1] = 1;
    	while(!q.empty()){
    		int x = q.front();
    		q.pop();
    		for(int i  = head[x]; i != -1; i = edge[i].nxt){
    			int y = edge[i].to;
    			if(d[y]) continue;
    			d[y] = d[x] + 1;
    			f[y][0] = x;
    			for(int j = 1; j <= t; ++ j)
    				f[y][j] = f[f[y][j - 1]][j - 1];
    			q.push(y);
    		}
    	}
    }
    
    int LCA(int x, int y){
    	if(d[x] > d[y]) swap(x, y);
    	for(int i = t; i >= 0; -- i)
    		if(d[f[y][i]] >= d[x]) y = f[y][i];
    	if(x == y) return x;
    	for(int i = t; i >= 0; -- i)
    		if(f[x][i] != f[y][i]) 
    			x = f[x][i], y = f[y][i];
    	return f[x][0];
    }
    
    
    
    int main()
    {
    	memset(head, -1, sizeof(head));
    	scanf("%d%d",&n,&m);
    	t = (int)(log(n) / log(2)) + 1;
    	for(int i = 1; i < n; ++ i){
    		int x, y;
    		scanf("%d%d",&x,&y);
    		add(x, y);
    		add(y, x);
    	}
    	bfs();
    	
    	while(m --){
    		scanf("%d",&k);
    		flag = 0;
    		int base = 0, maxx = 0;
    		for(int i = 1; i <= k; ++ i){
    			scanf("%d",&a[i]);
    			if(d[a[i]] > maxx){
    				maxx = d[a[i]];
    				base = a[i];
    			}
    		}
    		for(int i = 1; i <= k; ++ i){
    			if(base == a[i]) continue;
    			int lca = LCA(base, a[i]);
    			if(d[a[i]] - d[lca] > 1) flag = 1;
    		}
    		if(!flag) printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    树莓派研究笔记(2)-- 安装Nginx 服务器,PHP 和 SQLite
    树莓派研究笔记(1)-- 安装Mono
    Qemu虚拟机 玩树莓派最新版系统 (截止2017-04-10)
    CLRInjection
    CLRMonitor
    Xamarin Mono for VS开发窗体标题(Title)乱码解决方案
    精美3D中国象棋
    怀旧系列(5)----大学时代的疯狂
    怀旧系列(4)----文曲星编程GV-Basic
    怀旧系列(3)----Pascal
  • 原文地址:https://www.cnblogs.com/A-sc/p/12726243.html
Copyright © 2011-2022 走看看