很久很久以前,有一棵樹加入了 uoj 群。
這天,在它討論「一棵樹應該怎麼旋轉」的時候一不小心被刪除了,變成了被刪除的樹。
突然間,它突然發現它失去了顏色,變成了一棵純白的樹。這讓它感覺很焦躁,於是它來拜託你給自己染上一些顏色。
我們可以把它描述成一棵n個節點的有根樹(預設樹的根為1號節點),所有非根的度數為1的節點被稱為葉子節點。最開始所有的點都是白色的。
現在你需要選出一些節點並把這些節點染成黑色的。為了迎合樹的審美,你的染色方案必須要滿足所有葉子節點到根路徑上的黑色節點個數相同。
你發現黑色節點個數越多,樹就會越高興,所以你想要知道在所有合法的染色方案中,黑色節點總個數最多是多少。
神題。(感覺uoj round的題全是神題)
$o(n^2)$的dp大家都會,但是跟正解並沒有什麼關係;
顯然題目要求相當於使白色節點最少;
有幾個結論:
1.如果一種合法方案中根節點到所有葉節點的路徑上都經過白色節點,那麼dfs一遍這棵樹,在遇到白色節點時染黑並回溯,這樣必定可以使得白色節點變少或不變且依然合法;
2.如果一種合法方案中根節點到深度最淺的葉節點的路徑上經過白色節點,那麼根節點到所有葉節點的路徑上必定都經過白色節點;假定根節點深度為1,因為其他葉節點的深度不小於到最淺葉節點的深度,而根節點到其他葉節點路徑上的黑節點數等於到最淺葉節點路徑上的黑節點數,而小於他們的深度,因此根節點到其他葉節點的路徑上都會經過至少乙個白點;
綜上,一種最優的合法方案必定滿足根節點到最淺葉節點的路徑上沒有白點;
這樣一種構造方法就是先把根節點到最淺葉節點的路徑全部染黑,然後遞迴判斷根節點的其他子樹跟是否要染白再往下做即可;
簡化到每個點,實際上乙個點被染白當且僅當該節點子樹中最淺葉節點的深度》整棵樹的最淺葉節點深度+該節點到根節點路徑上的白點個數;
預處理每個點子樹中的最淺葉節點深度,再一次dfs判斷即可,時間複雜度$o(n)$。
1 #include2 #include3 #include4 #include5 #include6 #include7#define inf 2147483647
8#define eps 1e-9
9using
namespace
std;
10 typedef long
long
ll;11 typedef double
db;12
struct
edgea[200001
];15
int n,u,v,ans=0,tot=0,du[100001],mid[100001],head[100001
];16
void add(int u,int
v)21
void dfs(int u,int fa,int
dpt)29}
30}31void _dfs(int u,int fa,int
nwd)
36for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next)
41} 42}
43int
main()
54 dfs(1,0,1
);55 _dfs(1,0,mid[1
]);56 printf("
%d",n-ans);
57return0;
58 }
uoj140 UER 4 被粉碎的數字
題目 看起來就像是數字 rm dp 不妨從豎式乘法的角度來考慮這個問題 為了方便處理進製,我們得從低位向高位填數 設 dp i 0 1 j p t 表示填到了第 i 位,卡不卡上界,f x j f k times x p 不計算最高位 需要向最高位進 t 的 x 有多少個 這裡的卡上界比較奇怪,如果...
uoj 209 UER 6A 票數統計
給出n個數,每個數是0或1.再給出m個限制,每個限制 x,y 表示 前x個數中有y個1 或 後y個數中有x個1 求這樣的序列的個數。n 5000,m 1000 再一次被uer給虐了。其實這道題劼鏼爺已經講的很清楚了。撲通撲通跪下來 當x y的時候,很顯然已經確定這個限制是限制字首還是字尾的。當x y...
UOJ 209 UER 6 票數統計
原題鏈結 妹滋滋是乙個善於程式設計的女孩子。但是某一天,她一不小心把 uoj 後台的票數統計程式寫錯了。本來嘛在這種根本沒有什麼用的功能上出了 bug 也沒有什麼大關係,但是又有某一天,uoj 突然就開始搞全民公投了。這可怎麼辦呢?如果這個訊息讓別人知道的話自己肯定會被查表,更不要說讓所有使用者重新...