樹形dp 貪心思維 訊息傳遞(洛谷 P2018)

2021-10-23 03:55:45 字數 1785 閱讀 6449

題目描述

巴蜀國的社會等級森嚴,除了國王之外,每個人均有且只有乙個直接上級,當然國王沒有上級。如果a是b的上級,b是c的上級,那麼a就是c的上級。絕對不會出現這樣的關係:a是b的上級,b也是a的上級。

最開始的時刻是0,你要做的就是用1單位的時間把乙個訊息告訴某乙個人,讓他們自行散布訊息。在任意乙個時間單位中,任何乙個已經接到訊息的人,都可以把訊息告訴他的乙個直接上級或者直接下屬。

現在,你想知道:

1.到底需要多長時間,訊息才能傳遍整個巴蜀國的所有人?

2.要使訊息在傳遞過程中消耗的時間最短,可供選擇的人有那些?

輸入格式

輸入檔案的第一行為乙個整數n(n≤1000),表示巴蜀國人的總數,假如人按照1到n編上了號碼,國王的編號是1。第2行到第n行(共n-1行),每一行乙個整數,第i行的整數表示編號為i的人直接上級的編號。

輸出格式

檔案輸出共計兩行:

第一行為乙個整數,表示最後乙個人接到訊息的最早時間。

第二行有若干個數,表示可供選擇人的編號,按照編號從小到大的順序輸出,中間用空格分開。

首先,這題看上去是單向邊,以為是有根樹,其實可以發現,如果乙個點為根,那麼其它與它直接相連的都是它的兒子,所以是無根樹;

可以列舉每個點為根,size[i]表示以 i 為根的傳遞時間(注意不是最小);

然後可以發現如果 i 的兒子的所需傳遞時間越大,那麼越要第乙個從 i 傳給它,貪心思維體現;

最後ans要加1,因為傳給根結點也要1單位時間;

**:

#include

#define ll long long

#define pa pair

#define ls k<<1

#define rs k<<1|1

#define inf 0x3f3f3f3f

using

namespace std;

const

int n=

1100

;const

int m=

2000100

;const

int mod=

1e9;

int n,head[n]

,cnt;

int dp[n]

,size[n]

;struct nodeedge[n*2]

;void

add(

int p,

int q)

bool

cmp(

int p,

int q)

intdfs

(int p,

int q)if(

!cnt)

return0;

sort

(size+

1,size+cnt+

1,cmp)

;for

(int i=

1;i<=cnt;i++

) tim=

max(size[i]

+i,tim)

;return tim;

}int

main()

int ans=

2e9;

for(

int i=

1;i<=n;i++

) cout<1

int i=

1;i<=n;i++)if

(dp[i]

==ans) cout<" ";

return0;

}

洛谷 P2018 訊息傳遞 樹形dp 貪心

巴蜀國的社會等級森嚴,除了國王之外,每個人均有且只有乙個直接上級,當然國王沒有上級。如果a是b的上級,b是c的上級,那麼a就是c的上級。絕對不會出現這樣的關係 a是b的上級,b也是a的上級。最開始的時刻是0,你要做的就是用1單位的時間把乙個訊息告訴某乙個人,讓他們自行散布訊息。在任意乙個時間單位中,...

洛谷P2018 訊息傳遞

巴蜀國的社會等級森嚴,除了國王之外,每個人均有且只有乙個直接上級,當然國王沒有上級。如果a是b的上級,b是c的上級,那麼a就是c的上級。絕對不會出現這樣的關係 a是b的上級,b也是a的上級。最開始的時刻是0,你要做的就是用1單位的時間把乙個訊息告訴某乙個人,讓他們自行散布訊息。在任意乙個時間單位中,...

洛谷P2018 訊息傳遞

由題意得這是一棵樹,而任何乙個已經接到訊息的人,都可以把訊息告訴他的乙個直接上級或者直接下屬,說明是一棵無根樹。本來以為要用什麼高階樹上演算法亂搞,結果發現 n leq 1000 這不是dfs就能水過嗎?實際上是個樹規 欽定乙個結點為根,我們在有根樹上做樹規。對於結點 x 他的狀態由他的子結點決定。...