典型樹形dp
這裡,我們應該看到一些基本性質:
①:如果這個邊不能改(不是沒有必要改),我們就不改,因為就算改過去還要改回來,顯然不是最優的
注意:「不能改」是指邊的性質和要求的相同而不包括對邊的顏色沒有要求的情況!
②:如果我們每翻轉一條邊,就認為將這條邊的兩個端點度數+1,那麼不難看到,最後翻轉的所有邊構成的路徑總數就是度數為奇數點個數的1/2
(性質②的證明:一條路徑只會對兩端的點產生度數上的影響,而中間的點都是+2,還是偶數,所以無影響)
接下來,我們進行dp:
記狀態f[i][0/1]代表以i為根節點的子樹,0/1代表根節點與父親的邊是否翻轉
那麼我們可以看到,這個dp包含兩部分內容,一部分要保證路徑數最少,另一部分要保證在滿足路徑數最小的前提下路徑總長度最小,所以我們需要同時更新這兩個值,這樣用pair就是乙個比較好的選擇
接下來我們考慮更新:
在更新時我們使用兩個參量:p和q,作為更新dp的中間步驟,用p代表不以i為端點做鏈,q代表以i為端點做鏈,設i的某個子節點為to,於是有:
其中p初始化為(0,0),q初始化為(inf,inf)
解釋一下:這裡pair的add就是對應元素相加(手寫!非內建!)
而min操作表示先按pair第一關鍵字比較,再按第二關鍵字比較
那麼這一步就是乙個合併的過程:
首先,i不作為鏈的端點:分兩類來合併:如果子節點與i的邊翻轉了,那麼就要累在以i為端點的鏈裡(因為i與父親的邊不翻轉,那麼i就將是個端點),如果子節點與i的邊沒有翻轉,那麼僅針對這棵子樹而言,i並沒有作為路徑的端點,所以更新沒有以i為端點鏈的代價
如果i作為鏈的端點,同樣分兩類來合併:如果子節點與i的邊翻轉了,那麼i顯然可以成為鏈的端點,前提是在此之前i並不是鏈的端點,所以用之前i不是鏈的端點的代價來更新;反之,如果子節點與i的邊沒有翻轉,那麼就此而言i並不是端點,可要求i是鏈的乙個端點,這樣就必須用i原先就是鏈的端點的代價來更新
遍歷根節點所有子節點後,更新dp:
如果i與父親的邊沒有翻轉。即狀態dp[i][0]:
首先,i不作為鏈的端點肯定是一種可能性,直接比較
接著,如果i是鏈的乙個端點,i和父節點的邊還沒有翻轉,那麼說明在這個狀態下i是真正的奇度點,所以將狀態q的first+1後更新
如果i與父親的邊翻轉了,同樣分兩類更新:
首先,i本身作為了鏈的端點,而由於i本身就是奇度點,所以僅需將q.second+1來更新即可
還有,如果i本身在下面並沒有作為鏈的端點,而i卻與父節點的邊發生了翻轉,所以i就成為了新的奇度點,同時鏈長還增加了,所以p.first,p.second均增加即可
最後答案即為dp[1][0].first/2,dp[1][0].second
#include #include #include #include #include #include #include #include #define inf 0x3f3f3f3f
using namespace std;
struct edge
edge[200005];
int head[100005];
int cnt=1;
pair dp[100005][2];
int n;
void init()
void add(int l,int r,int w)
pairaddp(paira,pairb)
void dfs(int x,int fx,int typ)
dfs(to,x,edge[i].val);
pair temp1,temp2;
temp1=min(addp(p,dp[to][0]),addp(q,dp[to][1]));
temp2=min(addp(p,dp[to][1]),addp(q,dp[to][0]));
p=temp1;
q=temp2;
} if(typ==2||typ==0)
else
if(typ==2||typ==1)
else }
int main()
else
}dfs(1,1,0);
printf("%d %d\n",dp[1][0].first/2,dp[1][0].second);
return 0;
}
雅禮 noip2018 模擬賽day3 T2
典型的狀壓思想 設0表示黑球,1表示白球,用一串01序列代表剩下的球的狀態,記f i 表示在i狀態下取球的最大期望 那麼可以利用記憶化搜尋更新,每一層列舉可能拿走的球然後向下搜尋,同時記憶化即可 在狀態中刪去乙個點可以利用位運算實現 同時要注意乙個問題,就是狀態0010和狀態010並不是相同的狀態,...
NOIP2018模擬賽2018 10 18 輕功
description 題目背景 尊者神高達進入了基三的世界,作為乙個 mmorpg 做任務是必不可少的,然而跑地圖卻令人十分不爽。好在基三可以使用輕功,但是尊者神高達有些手殘,他決定用梅花樁練習輕功。題目描述 一共有 n 個木樁,要求從起點 0 開始,經過所有梅花樁,恰好到達終點 n,尊者神高達一...
NOIP2018模擬賽2018 10 18 開荒
description 題目背景 尊者神高達作為乙個萌新,在公升級路上死亡無數次後被乙隻大黃嘰帶回了師門。他加入師門後發現有無窮無盡的師兄弟姐妹,這幾天新副本開了,尊者神高達的師門作為乙個 pve師門,於是他們決定組織一起去開荒。題目描述 師門可以看做以 1 為根的一棵樹,師門中的每乙個人都有一定的...