zoukankan      html  css  js  c++  java
  • 牛客网 漂亮的树

    https://ac.nowcoder.com/acm/contest/5902/C

    感谢LDK大神提供的最后解法

    一个点z   到另一个点集合S的最长路为 ans

    集合S中的最远点对x,y

    ans = max(ans,dis(x,z),dis(y,z));

    就是这样了

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<unordered_map>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 7;
    vector<int>G[maxn], ins[maxn];
    unordered_map<int, int >id;
    int n;
    void add(int x, int y) {
    	G[x].push_back(y);
    }
    int dep[maxn], top[maxn],  fa[maxn], siz[maxn];
    int cns[maxn];
    int son[maxn];
    
    int dfs1(int x, int f, int d) {
    	dep[x] = d;
    	fa[x] = f;
    	siz[x] = 1;
    	int s = 0;
    	for (int i = 0; i < G[x].size(); i++) {
    		int p = G[x][i];
    		if (p == f) continue;
    		dfs1(p, x, d + 1);
    		siz[x] += siz[p];
    		if (s < siz[p]) {
    			s = siz[p];
    			son[x] = p;
    		}
    	}
    	return 0;
    }//haah
    
    int cnt = 0;
    int dfs2(int x, int t) {
    	top[x] = t;
    	if (!son[x]) return 0;
    	dfs2(son[x], t);//重儿子重复利用t
    
    	for (int i = 0; i < G[x].size(); i++) {
    		int p = G[x][i];
    		if (p == fa[x] || p == son[x]) continue;
    		dfs2(p, p);//轻儿子新建t
    	}
    	return 0;
    }
    
    int LCA(int u, int v)
    {
    	while (top[u] != top[v])//u、v不在同一条重链上时
    	{
    		if (dep[top[u]] > dep[top[v]])//将深度大的上提
    			u = fa[top[u]];
    		else
    			v = fa[top[v]];
    	}
    	if (dep[u] < dep[v])//返回u、v中在较上方的那个
    		return u;
    	return v;
    }
    
    int get(int x, int y) {//点之间的距离
    	int root = LCA(x, y);
    	return dep[x] + dep[y] - 2 * dep[root];
    }
    
    int main() {
    	//******准备*********//
    
    	int q;
    	scanf("%d %d", &n, &q);
    	int x;
    	int c = 0;
    	for (int i = 1; i <= n ; i++) {
    		scanf("%d", &x);
    		cns[i] = x;
    		if (id[x] == 0) id[x] = ++c;
    		ins[id[x]].push_back(i);
    	}
    
    	for (int i = 1; i < n; i++) {
    		int x, y;
    		scanf("%d%d", &x, &y);
    		add(x, y);
    		add(y, x);
    	}
    	dfs1(1, -1, 0);
    	dfs2(1, 1);
    
    	
    	//******开始********//
    	for (int i = 1; i <= n; i++) {
    		if (ins[i].size() < 2) continue;
    		int s = ins[i][0];
    		int t = ins[i][1];
    		int ln = get(s, t);
    
    		for (int j = 2; j < ins[i].size(); j++) {
    			int x = ins[i][j];
    			int a = get(x, s);
    			int b = get(x, t);
    			if (a > b) {
    				if (a > ln) {
    					ln = a;
    					t = x;
    				}
    			}
    			else {
    				if (b > ln) {
    					ln = b;
    					s = x;
    				}
    			}
    		}
    		ins[i].clear();
    		ins[i].push_back(s);
    		ins[i].push_back(t);
    	}
    
    	while (q--) {
    		int x, y;
    		int ans = 0;
    		scanf("%d%d", &x, &y);
    		x = id[x];
    		y = id[y];
    		
    		if (ins[x].size() == 0 || ins[y].size() == 0) {
    			printf("0
    ");
    		}
    		else {
    			for (int i = 0; i < ins[x].size(); i++) {
    				for (int j = 0; j < ins[y].size(); j++) {
    					int s = ins[x][i];
    					int t = ins[y][j];
    					ans = max(get(s, t), ans);
    				}
    			}
    			printf("%d
    ", ans);
    		}
    	}
    	return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    Wrong codepoints for non-ASCII characters inserted in UTF-8 database using CLP
    SqlException with message "Caught java.io.CharConversionException." and ERRORCODE=-4220
    XSD 数据类型
    Can't read [proguard.ClassPathEntry@1a0c10f] (No such file or directory)
    ubuntu 创建swap分区
    tar分层压缩
    MTK 自定义系统服务
    MTK framework系统默认设置
    MTK 修改默认屏幕亮度
    MTK 隐藏底部状态栏
  • 原文地址:https://www.cnblogs.com/lesning/p/13033656.html
Copyright © 2011-2022 走看看