zoukankan      html  css  js  c++  java
  • P3128 [USACO15DEC]Max Flow P(LCA 树上差分)

    传送门

    刚学LCA,做一下树上差分的题目。

    很明显的一道树上差分的题目且是点差分,从差分数组的思想延伸到树上差分,对于树上的一条路,假设要将a-b路径上的所有点都加上一个值,那么只需要在a点和b点加上这个值,并且在两者的LCA处及LCA的父节点上都减去这个值就可以了,因为最后在进行由下到上的递归过程中,LCA节点会被重复计算两次,这样就能保证只计算一次。
    由于这道题要求的是整张图上的最大值,只需要从根节点遍历一遍同时维护一个最大值就可以了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5 + 10, M = 2e5 + 10;
    struct Edge{
    	int v, next;
    }edge[M];
    int dep[N], fa[N][22], maxn = -1;
    int tot, head[N], mark[N];
    void add(int u, int v){
    	edge[tot].next = head[u];
    	edge[tot].v = v;
    	head[u] = tot ++;
    }
    
    void dfs(int now, int pre){
    	dep[now] = dep[pre] + 1;
    	fa[now][0] = pre;
    	for(int i = head[now]; i != -1; i = edge[i].next){
    		int v = edge[i].v;
    		if(v != pre)
    			dfs(v, now); 
    	}
    }
    
    int getlca(int u, int v){
    	if(dep[u] < dep[v])
    		swap(u, v);
    	while(dep[u] > dep[v])
    		u = fa[u][(int)log2(dep[u] - dep[v])];
    	if(u == v)
    		return u;
    	for(int i = 20; i >= 0; i --)
    		if(fa[u][i] != fa[v][i])
    			u = fa[u][i], v = fa[v][i];
    	return fa[u][0];
    }
    
    int dfslca(int node, int pre){
    	for(int i = head[node]; i != -1; i = edge[i].next){
    		int v = edge[i].v;
    		if(v != pre){
    			dfslca(v, node);
    			mark[node] += mark[v];
    		}
    	}
    	maxn = max(maxn, mark[node]);
    }
    
    
    int main(){
    	int n, k;
    	scanf("%d%d", &n, &k);
    	memset(head, -1, sizeof head);
    	for(int i = 1; i < n; i ++){
    		int a, b;
    		scanf("%d%d", &a, &b);
    		add(a, b);
    		add(b, a);
    	}
    	dfs(1, 0);
    	for(int j = 1; j <= 20; j ++)
    		for(int i = 1; i <= n; i ++)
    			fa[i][j] = fa[fa[i][j - 1]][j - 1];
    	
    	for(int i = 1; i <= k; i ++){
    		int a, b;
    		scanf("%d%d", &a, &b);
    		int lca = getlca(a, b);
    		mark[a] ++;
    		mark[b] ++;
    		mark[lca] --;
    		mark[fa[lca][0]] --;	
    	}
    	maxn = -1;
    	cout << dfslca(1, -1) << endl;
    	return 0;
    } 
    
  • 相关阅读:
    .Net Core小技巧
    调用Kubernetes API操作Kubernetes
    在CentOS 7+ 安装Kubernetes入门(单Master)
    Linux命令行基础
    使用wireshark学习TCP
    Redis原子性写入HASH结构数据并设置过期时间
    Vue使用小结
    JAVA & .NET创建对象构造函数调用顺序
    .NET 中的序列化 & 反序列化
    ASP.NET Core中使用Graylog记录日志
  • 原文地址:https://www.cnblogs.com/pureayu/p/14972521.html
Copyright © 2011-2022 走看看