• 【树上差分】P3128 [USACO15DEC]Max Flow P


    【树上差分】P3128 [USACO15DEC]Max Flow P

    传送门

    image

    • 题意

      FJ给他的牛棚的N个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。

      FJ有K条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。

      隔间\(s_i\)\(lca(s_i,t_i)\),再到\(t_i\)这条路径上所有的点的值都要进行加1操作。

      而如果直接沿着这条路径对每一个结点进行+1操作,那是一个非常巨大的工作量。

      于是可以借助差分的思想和dfs的特性来只对四个点进行修改,一个是\(t_i\),另外一个是\(s_i\),再一个是\(lca(t_i,s_i)\),还有一个是\(fa(lca(t_i,s_i))\)

      前两者进行加一标记,后两者进行减一操作,对lca进行减一是因为多算了一个,对lca的父亲结点进行减一是因为取消这条链上的影响

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    #define PB push_back
    using namespace std;
    const int N = 5E4+500,logs = 18;
    int n,m,k;
    vector<int > g[N]; 
    int dep[N],fa[N][logs+2],val[N];
    void pre_dfs(int u,int from)
    {
    	dep[u] = dep[from] + 1 , fa[u][0] = from;
    	for(int i = 0;fa[u][i];i++) fa[u][i+1] = fa[ fa[u][i] ][i]; 
        for(auto v:g[u])
    	{
    		if(v==from) continue;
    		pre_dfs(v,u);
    	}	
    } 
    
    int get_lca(int lowu,int u)
    {
        if(dep[lowu]<dep[u]) swap(lowu,u);
    	for(int i = logs;i>=0;i--) if(dep[lowu]-(1<<i)>=dep[u]) lowu = fa[lowu][i];
    	if(lowu==u) return u;
        for(int i=logs;i>=0;i--) if(fa[lowu][i]!=fa[u][i]) lowu = fa[lowu][i],u = fa[u][i];
        
        return fa[u][0];			
    }
    
    int ans;
    void get_ans(int u,int from)
    {
    	for(auto v:g[u])
    	{
    		if(v==from) continue;
    		get_ans(v,u);
    		val[u] += val[v];
    	}
    	ans = max(ans,val[u]);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>k;
        repd(i,1,n-1)
        {
        	int u,v;
        	cin>>u>>v;
        	g[u].PB(v),g[v].PB(u);
    	}
    	pre_dfs(1,0);
    	repd(i,1,k)
    	{
    		int u,v;
    		cin>>u>>v;
    		int lca = get_lca(u,v);
    	    val[u]++,val[v]++,val[lca]--,val[ fa[lca][0] ]--;
    	}
    	get_ans(1,0);
    	cout<<ans;
        return 0;
    
    }
    
    
  • 相关阅读:
    利用PHP SOAP实现WEB SERVICE
    PHP 简单的加密解密算法
    Java 简单的加密解密算法
    去掉php框架CI默认url中的index.php
    PHP 日期计算函数【差异天数】
    PHP生成迅雷、快车、旋风等软件的下载链接代码实例
    转:苹果iphone APP界面设计尺寸官方版
    iOS开发——密码存储之keychain的使用
    Simple iPhone Keychain Access
    View的简单说明
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/16020250.html
Copyright © 2020-2023  润新知