Accumulation Degree题解
原題傳送門
題目大意:有一個樹形的水系,其中有nnn個節點,有n?1n-1n?1條邊。xxx,yyy兩點之間的容量用c(x,y)c(x,y)c(x,y)表示。nnn個點中有一個點可以作為源點,可以不斷地流出水。所有度數為111的點都為匯點,水可以從該點流出。然后求以哪個點作為源點可以使得整個水系的流量最大。
先來考慮暴力,我們取每個點為源點,然后這個就成了個有根樹。
現在以第666號節點為源點
不難發現,每個點都是從它的父親節點獲得水,并流向它的兒子節點
用D[x]D[x]D[x]來表示以xxx為根的子樹中,從xxx出發流向子樹的最大流量
D[x]=∑y∈Son(x){min(D[y],c(x,y))y的度數>1c(x,y)y的度數=1D[x]=\sum_{y\in Son(x)}\begin{cases} min(D[y],c(x,y))& y的度數>1\\ c(x,y)& y的度數=1 \end{cases} D[x]=y∈Son(x)∑?{min(D[y],c(x,y))c(x,y)?y的度數>1y的度數=1?
對于我們要枚舉的每個源點sss,可以用樹形DP求出D[x]D[x]D[x]數組
但是枚舉每個根節點的復雜度是承受不了的。
此時我們就得用不那么暴力的換根法
用二次掃描與換根法代替源點的枚舉
先任選一個源點為根節點,設該點為rootrootroot,用上面的函數跑一遍,得到DrootD_{root}Droot?
設F[x]F[x]F[x]為把xxx作為源點的最大流量。對于我們設的根節點rootrootroot,顯然有D[root]=F[root]D[root]=F[root]D[root]=F[root]
若F[x]F[x]F[x]已經知道了,則考慮其子節點yyy,F[y]F[y]F[y]分為兩部分:
1.從yyy流向以yyy為根的子樹的流量,已經計算并存在D[y]D[y]D[y]中了
2.從yyy沿著父親節點的路線,流到其他的節點。
因為把xxx作為源點的總流量為F[x]F[x]F[x],從xxx流向yyy的流量為min(D[y],c(x,y))min(D[y],c(x,y))min(D[y],c(x,y)),所以從xxx流向除yyy以外的其他部分的流量就是它們的差。
因此將yyy作為源點,先流到xxx,再流向其他部分的流量就是這個差災區和c(x,y)c(x,y)c(x,y)取最小值的結果
F[y]=D[y]+{min(F[x]?min(D[y],c(x,y)),c(x,y))x的度數>1c(x,y)x的度數=1F[y]=D[y]+\begin{cases} min\left(F[x]-min(D[y],c(x,y)),c(x,y)\right)& x的度數>1\\ c(x,y)&x的度數=1 \end{cases} F[y]=D[y]+{min(F[x]?min(D[y],c(x,y)),c(x,y))c(x,y)?x的度數>1x的度數=1?
F[y]F[y]F[y]就是把源點從xxx換成yyy后,流量的計算結果。
最后的代碼就不貼了,就是求出fff數組之后求個maxmaxmax就完事了
總結
以上是生活随笔為你收集整理的Accumulation Degree题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Words Accumulation
- 下一篇: LinuxGit Accumulatio