P3128 [USACO15DEC]Max Flow P
生活随笔
收集整理的這篇文章主要介紹了
P3128 [USACO15DEC]Max Flow P
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
P3128 [USACO15DEC]Max Flow P
樹上差分之點差分模板題
題目描述:
FJ給他的牛棚的N(2≤N≤50,000)個隔間之間安裝了N-1根管道,隔間編號從1到N。所有隔間都被管道連通了。
FJ有K(1≤K≤100,000)條運輸牛奶的路線,第i條路線從隔間si運輸到隔間ti。一條運輸路線會給它的兩個端點處的隔間以及中間途徑的所有隔間帶來一個單位的運輸壓力,你需要計算壓力最大的隔間的壓力是多少。
題解:
樹上差分 分為 點差分 和 邊差分
點差分:
比如講紅色到綠色路徑上的點都+x,求差分數組那么我們就對紅色點和綠色點分別加上x,對黃色點減x,對黃色點的父親節點減x。為什么呢?點差分求和時是從葉子節點開始往根上并,因為我們紅綠都加x,合并時黃色就會加兩個x(一個來自左邊,一個右邊),所以黃色要減x,為了避免影響到其他路徑,所以黃色節點的父親節點要減x,其實跟數組的差分本質也是一樣的
邊差分:
同樣是對紅色到綠色的路徑加x,我們要在黃色點處減2x,這樣就使得加x的效果只局限在u…v,不會向lca(u,v)的爸爸蔓延。這是邊的累加情況,仔細考慮考慮
黃色點是紅和綠的lca,所以還要用到lca算法
代碼:
#include<bits/stdc++.h> typedef long long ll; using namespace std; inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } int siz; const int maxn=5e4+9; vector<int>edge[maxn]; int fa[maxn][30],dep[maxn],dt[maxn]; void dfs(int x) {for(int i=1;i<=siz;i++){fa[x][i]=fa[fa[x][i-1]][i-1];}for(int i=0;i<edge[x].size();i++){int v=edge[x][i];if(v!=fa[x][0]){fa[v][0]=x;dep[v]=dep[x]+1;dfs(v);}} } int LCA(int u,int v) {if(dep[u]<dep[v])swap(u,v);int de=dep[u]-dep[v];for(int x=0;x<=siz;x++){if((1<<x)&de)u=fa[u][x];}if(u==v)return u;for(int x=siz;x>=0;x--){if(fa[u][x]!=fa[v][x]){u=fa[u][x];v=fa[v][x];}} return fa[u][0]; } int ans=0; void dfs_cnt(int x) {for(int i=0;i<edge[x].size();i++){int v=edge[x][i];if(v!=fa[x][0]){dfs_cnt(v);dt[x]+=dt[v];}ans=max(ans,dt[x]);} } int main() {int n,m;cin>>n>>m;siz=log2(n);for(int i=1;i<n;i++){int x,y;cin>>x>>y;edge[x].push_back(y);edge[y].push_back(x);}dfs(1);for(int i=1;i<=m;i++){int x,y;cin>>x>>y;int z=LCA(x,y);dt[z]--;dt[fa[z][0]]--;dt[x]++;dt[y]++;}dfs_cnt(1);cout<<ans<<endl;return 0; }總結
以上是生活随笔為你收集整理的P3128 [USACO15DEC]Max Flow P的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CPU虚拟化的三种技术
- 下一篇: Codeforces Round #69