本題當然可以用樹剖解決,而且是樹剖的模板題。但是對於本題來說,有一種更巧妙的辦法
樹上差分
類似於普通的差分,我們對於題目中的每一條路線i->j,把它拆成i->lca(i,j)->j.然後將i點、j點的權值加一,將lca(i,j)的權值減二
乍看起來沒什麼毛病,但是仔細想想,對lca(i,j)的子樹進行字首和,則lca(i,j)點的權值加二又減二,而題目要求lca(i,j)權值應當+1
所以我們將lca(i,j)的權值減一,將lca(i,j)的父親的權值減一,這樣就能符合題意了
差分之前預處理每個點的祖先,lca+差分即可
1 #include 2 #include 3 #include 4 typedef longac codelong
ll;5 inline int
read()
9while(c<='
9'&&c>='
0') ret=ret*10+c-'
0',c=getchar();
10return ret*f;11}
12using
namespace
std;
13int
n,k;
14struct
edge a[50010
<<1
];17
int num,head[50010
<<1
];18
int sum[50010
],ans;
19int d[50010],fa[50010][31
];20 inline void add(int
from,int
to)
25void find(int u,int
f) 34}35
int lca(int x,int
y) 41
for(int i=30;i>=0;i--)
42if(fa[x][i]!=fa[y][i])
46return fa[x][0
];47}48
void dfs(int u,int
f) 55 ans=max(ans,sum[u]);56}
57int
main()
69 dfs(1,0
);70 printf("
%d\n
",ans);
71return0;
72 }
洛谷3128 最大流(樹鏈剖分)
蒟蒻並不會樹上差分。所以只能用樹鏈剖分套線段樹維護。對於每條路徑,都相當於將所有經過的點 1,最後查詢最大值即可。includeusing namespace std const int maxn 5e4 10 const int maxm 1e5 10 int n,q,cnt int head m...
洛谷P3128USACO最大流 樹上差分入門
一道樹上差分的入手好題,中文題面不再贅述 讀完題後,我們發現,答案就是圖中的點被經過的最多次數,即有多少條路徑經過它,暴力期望得分20 40分,正解是什麼呢?樹上差分 lca 沒錯,和差分的操作一樣,在區間的左端點加一,在右端點 1的位置減一,只不過放到了樹上,我們先預處理每個點的lca,之後我們發...
洛谷 P4722 最大流最快模板
題意 直接給出網路流建圖資訊,求最大流 一般的dinic演算法和isap演算法複雜度為o n 2m 此題有專門資料會卡這兩個演算法。因此一種複雜度上界在常用最大流演算法中最優的最高標號預留推進演算法 又叫hlpphlpp 其上界為o n 2 sqrt m 並且在經過優化後這種演算法在資料隨機的情況下...