1. 程式人生 > >洛谷P2018 消息傳遞

洛谷P2018 消息傳遞

ostream 一個 位置 pri 思路 str string mes fff

P2018 消息傳遞

題目描述

巴蜀國的社會等級森嚴,除了國王之外,每個人均有且只有一個直接上級,當然國王沒有上級。如果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的人直接上級的編號。

輸出格式:

文件輸出共計兩行:

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

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

輸入輸出樣例

輸入樣例#1:
8
1
1
3
4
4
4
3
輸出樣例#1:
5
3 4 5 6 7
/*
    樹形dp
    思路:枚舉第一個放的位置,dfs遞歸處理出當前節點u的子節點v需要的傳遞時間,然後從大到小排序,對於傳遞時間長的節點,就先傳遞給它。
*/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1010 using namespace std; int ans=0x7fffffff,an[maxn],dp[maxn],n,num,head[maxn],ans_num; struct node{ int pre,to; }e[maxn*2]; void Insert(int from,int to){ e[++num].to=to; e[num].pre
=head[from]; head[from]=num; } void dfs(int now,int father){ int cnt=0,tmp[maxn]; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==father)continue; dfs(to,now); tmp[++cnt]=dp[to]; } sort(tmp+1,tmp+cnt+1); for(int i=1;i<=cnt;i++)dp[now]=max(dp[now],tmp[i]+cnt-i+1); } int main(){ freopen("Cola.txt","r",stdin); scanf("%d",&n); int x; for(int i=2;i<=n;i++){ scanf("%d",&x); Insert(x,i); Insert(i,x); } for(int i=1;i<=n;i++){ memset(dp,0,sizeof(dp)); dfs(i,0); if(ans>dp[i]){ ans=dp[i]; ans_num=0; } if(ans==dp[i])an[++ans_num]=i; } printf("%d\n",ans+1); for(int i=1;i<=ans_num;i++)printf("%d ",an[i]); return 0; }

洛谷P2018 消息傳遞