洛谷 P3621 APIO2007 風鈴 思維

2021-09-26 09:19:07 字數 2019 閱讀 8272

傳送門

給出一棵樹,要求我們通過最少的交換子樹的次數使得一棵樹的最小深度和最大深度差不大於1

11,且左子樹的深度要大於右子樹的

我們在樹上跑一次dfs

dfsdf

s,求出最大深度和最小深度

如果差大於1

11顯然無解

現在我們來考慮哪些情況是必然需要交換的,設1

11表示所有子樹的深度較大,2

22表示所有子樹的深度有大有小,0

00表示所有子樹的深度較小(比較的物件是另一顆子樹)

1.

1.1.

左子樹為0

00而右子樹為1

11,為了滿足題意必定需要一次交換

2.

2.2.

左子樹為2

22而右子樹為1

11,我們為了保證左子樹深度要更大,也需要一次交換,而左子樹為2

22的情況下,我們在之後對其子樹討論時再求解

3.

3.3.

左子樹為0

00而右子樹為2

22,與上面同理,為保證右子樹深度更小同樣要一次交換

這樣就是所有情況了嗎no,

no,n

ono,no,no

no,no,

no我們還有兩棵子樹狀態相同的情況沒有討論,當它們同時是0、1

0、10、

1時肯定不需要交換,當2

22時呢,按照題意,我們必須要把深度大的往左移,小的往右移,可我們不能交換兩個子樹內的子樹,所有這種情況是無解的

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

using namespace std;

inline ll read()

while

(s>=

'0'&&s<=

'9')

return d*f;

}int t[

100005][

3],mind=

2147483647/3

,maxd=0;

void

dig(

int k,

int dep)

dig(t[k][1

],dep+1)

;dig

(t[k][2

],dep+1)

;return;}

int ans=

0,tf=0;

intget

(int k,

int dep)

int a=

get(t[k][1

],dep+1)

,b=get

(t[k][2

],dep+1)

;if((a==

0&&b==1)

||(a==

2&&b==1)

||(a==

0&&b==2)

) ans++;if

(a==

2||b==2)

if(a+b==1)

return2;

else

if(a+b==2)

return1;

else

return0;

}int

main()

dig(1,

0);if

(maxd-mind>1)

return

!printf

("-1");

if(maxd==mind)

return

!printf

("0");

get(1,

0);if

(tf)

printf

("-1");

else cout

}

洛谷P3621 APIO2007 風鈴

你準備給弟弟 ike 買一件禮物,但是,ike 挑選禮物的方式很特別 他只喜歡那些能被他排成有序形狀的東西。你準備給 ike 買乙個風鈴。風鈴是一種多層的裝飾品,一般掛在天花板上。每個風鈴都包含一些由豎直線連起來的水平杆。每根杆的兩頭都有線連線,下面或者掛著另一根水平杆,或者掛著乙個玩具。下面是乙個...

洛谷 P2007 魔方

常神牛從來沒接觸過魔方,所以他要借助計算機來玩。即使是這樣,他還是很菜。常神牛家的魔方都是3 3 3的三階魔方,大家都見過。更正 3 4以圖為準。作為一名菜鳥,常神牛從網上搜了一篇攻略,並找人翻譯成了他自己會做的方法。現在告訴你他的魔方情況,以及他從網上搜到的攻略,請你求出最後魔方變成什麼樣子。輸入...

洛谷 P3629 APIO2010 巡邏

題目在這裡 這是乙個紫題,當然很難。我們往簡單的想,不建立新的道路時,從1號節點出發,把整棵樹上的每條邊遍歷至少一次,再回到1號節點,會恰好經過每條邊兩次,路線總長度為 2 n 1 根據樹的深度優先遍歷思想,很容易證明這個結論,因為每條邊必然被遞迴一次,回溯一次。建立1條新道路之後,因為新道路必須恰...