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;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    jQuery 语法
    jQuery 简介
    把数据存储到 XML 文件
    XML 注意事项
    XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。
    通过 PHP 生成 XML
    XML 命名空间(XML Namespaces)
    XML to HTML
    XMLHttpRequest 对象
    使用 XSLT 显示 XML
  • 原文地址:https://www.cnblogs.com/lesning/p/13033656.html
Copyright © 2011-2022 走看看