• HDU 4912 LCA + 贪心


    题意及思路

    说一下为什么按LCA深度从深到浅贪心是对的。我们可以直观感受一下,一条的路径会影响以这个lca为根的这颗树中的链,而深度越深,影响范围越小,所以先选影响范围小的路径。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100010;
    int head[maxn], Next[maxn * 2], ver[maxn * 2], tot, f[maxn][20];
    int deep[maxn], t;
    struct Edge {
    	int u, v, lca, lca_deep;
    	bool operator < (const Edge& rhs) const {
    		return lca_deep > rhs.lca_deep;
    	}
    };
    Edge a[maxn];
    bool v[maxn];
    void add(int x, int y) {
    	ver[++tot] = y;
    	Next[tot] = head[x];
    	head[x] = tot;
    }
    queue<int> q;
    void bfs() {
    	deep[1] = 1;
    	q.push(1);
    	while(!q.empty()) {
    		int x = q.front(); 
    		q.pop();
    		for (int i = head[x]; i; i = Next[i]) {
    			int y = ver[i];
    			if(deep[y]) continue;
    			deep[y] = deep[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 query(int x, int y) {
    	if(deep[x] > deep[y]) swap(x, y);
    	for (int i = t; i >= 0; i--) {
    		if(deep[f[y][i]] >= deep[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];
    }
    
    void dfs(int x, int fa) {
    	if(v[x]) return;
    	v[x] = 1;
    	for (int i = head[x]; i; i = Next[i]) {
    		int y = ver[i];
    		if(y == fa) continue;
    		dfs(y, x);
    	}
    }
    
    int main() {
    	int n, m, x, y;
    	while(~scanf("%d%d", &n, &m)) {
    		t = (int)(log(n) / log(2)) + 1; 
    		tot = 0;
    		for (int i = 1; i <= n; i++) {
    			head[i] = 0;
    			v[i] = 0;
    			for (int j = 0; j <= t; j++)
    				f[i][j] = 0;
    			deep[i] = 0;
    		}
    //		memset(head, 0, sizeof(head));
    //		memset(f, 0, sizeof(f));
    //		memset(v, 0, sizeof(v));
    //		memset(deep, 0, sizeof(deep));
    //		tot = 0;
    		for (int i = 1; i < n; i++) {
    			scanf("%d%d", &x, &y);
    			add(x, y);
    			add(y, x);
    		}
    		bfs();
    		int ans = 0;
    		for (int i = 1; i <= m; i++) {
    			scanf("%d%d", &a[i].u, &a[i].v);
    			a[i].lca = query(a[i].u, a[i].v);
    			a[i].lca_deep = deep[a[i].lca];
    		}
    		sort(a + 1, a + 1 + m);
    		for (int i = 1; i <= m; i++) {
    			if(!v[a[i].u] && !v[a[i].v]) {
    				ans++;
    				dfs(a[i].lca, f[a[i].lca][0]);
    			}
    		}
    		printf("%d
    ", ans);
    	}
    }
    

      

  • 相关阅读:
    java 求两个数最大值
    java 加法运算
    javs switch 语句
    git合并分支成功,但是push失败(remote: GitLab: You are not allowed to push code to protected branches on this project.)
    python 获取日期以及时间
    1713
    linux shell脚本中的延时
    java 类的继承
    Python3 使用企业微信 API 发送消息
    java if 条件语句
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10641275.html
Copyright © 2020-2023  润新知