zoukankan      html  css  js  c++  java
  • CF-div3-629-E

    思路分析

    题意:让我们树上找一条链,使得所有点都在链上,或者距这条链上一点的距离为1;
    分析:
    1.假如这个点到链上的距离为1,说明这个点的父亲在链上。
    2.首先想到思考如何去找这条链,就是去选另一个端点。肯定是从根出发到深度最深的点的这条链,因为端点deep越深,这条链能覆盖到的点越多嘛。
    3.接着只要判其它结点或者父亲与这个点是不是在一条链上就可以了。判是不是在一条链,只要判断lca(当前结点,最深结点) 是不是 = 当前结点 或者 当前结点的父亲。

    做法:树链剖分求出lca,father,deep,然后找到最深点,判断其它点与它的lca是否满足条件即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2e5+100;
    vector<int> g[maxn];
    int fa[maxn],depth[maxn],sz[maxn],son[maxn],id[maxn],rk[maxn],top[maxn],bot[maxn];
    int cnt = 0;
    int root;
    
    void dfs(int x,int deep){
    	depth[x] = deep;
    	sz[x] = 1;
    	for(int li = 0;li<g[x].size();li++){
    		int i = g[x][li];
    		if(i == fa[x]) continue;
    		fa[i] = x;
    		dfs(i,deep+1);
    		sz[x] += sz[i];
    		if(sz[i] > sz[son[x]]) son[x] = i;
    	}
    }
    
    void dfs2(int x,int tp){
    	top[x] = tp;
    	id[x] = ++cnt;
    	rk[cnt] = x;
    	if(son[x]) dfs2(son[x],tp),bot[x] = bot[son[x]];
    	else bot[x] = x;
    	for(int li=0;li<g[x].size();li++){
    		int i = g[x][li];
    		if(i != fa[x] && i != son[x])
    			dfs2(i,i);
    	}
    }
    
    int lca(int u,int v){
    	while(top[u] != top[v]){
    		if(depth[top[u]] < depth[top[v]]) swap(u,v);
    		u = fa[top[u]];
    	}
    	if(depth[u] < depth[v]) return u;
    	return v;
    }
    
    int node[maxn];
    void solve(){
    	int k;
    	cin>>k;
    	int maxDeep = 0,maxNode;
    	for(int i=1;i<=k;i++) {
    		cin>>node[i];
    		if(maxDeep <= depth[node[i]]){
    			maxDeep = depth[node[i]];
    			maxNode = node[i];
    		}
    	}
    	for(int i=1;i<=k;i++){
    		if(node[i] == maxNode) continue;
    		int LCA = lca(maxNode,node[i]);
    		if(!(LCA == node[i] || LCA == fa[node[i]])){
    			puts("NO");
    			return;
    		}
    	}
    	puts("YES");
    }
    
    int main(){
    	ios::sync_with_stdio(false);
    	int n,m;
    	cin>>n>>m;
    	for(int i=1;i<=n-1;i++){
    		int u,v;
    		cin>>u>>v;
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	root = 1;
    	dfs(root,1);
    	dfs2(root,root);
    	while(m--){
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    SQL Server ->> Natively Compiled Stored Procedures(本地编译存储过程)
    Linux ->> <user_name> not in the sudoers file. This incident will be reported.
    Linux ->> Ping命令
    Linux ->> UBuntu 14.04 LTE下主机名称和IP地址解析
    Linux ->> UBuntu ->> Could not get lock /var/lib/dpkg/lock
    Linux ->> scp命令复制对端机器上的文件/文件夹
    Linux ->> UBuntu 14.04 LTE下安装Hadoop 1.2.1(伪分布模式)
    Linux ->> UBuntu 14.04 LTE下设置静态IP地址
    .Net ->> iTextSharp工具读取PDF文本内容
    oracle case用法
  • 原文地址:https://www.cnblogs.com/fisherss/p/12580644.html
Copyright © 2011-2022 走看看