B - New Year Bonus Grant
Time Limit:
2000/1000MS (Java/Others)
Memory Limit:
128000/64000KB (Java/Others)
Special Judge
Problem Description
All programmers of Mocrosoft software company are organized in a strict subordination hierarchy. Every programmer has exactly one chief, except Bill Hates who is also the head of the company and has no chief.
Due to the celebration of the new 2003 year, chief accountant of Mocrosoft decided to pay a New Year Bonus Grant of 1000 dollars to some programmers. However being extremely concerned of the company wealth she would like to designate the least possible amount of money for these grants. On the other hand she didn’t want to be accused of being too greedy or of giving preferences to some programmers. To do this, she developed the following scheme of grants appointment:
• Each programmer may either assign a grant to one of his subordinates or have a grant assigned to him by his chief or none of the above.
• No programmer can simultaneously receive a grant and assign a grant to one of his subordinates.
• No programmer can assign a grant to more than one of his subordinates
The scheme seemed to be designed perfectly — nobody would like to assign a grant to anybody since in this case he himself would not receive money. But programmers somehow discovered the plan of chief accountant and decided to make a trick to get the most money possible and share them fairly afterwards. The idea was to make such grant assignments that the total amount of grant money received is maximum possible.
You were selected to write the program which will find the optimal grants appointment.
Due to the celebration of the new 2003 year, chief accountant of Mocrosoft decided to pay a New Year Bonus Grant of 1000 dollars to some programmers. However being extremely concerned of the company wealth she would like to designate the least possible amount of money for these grants. On the other hand she didn’t want to be accused of being too greedy or of giving preferences to some programmers. To do this, she developed the following scheme of grants appointment:
• Each programmer may either assign a grant to one of his subordinates or have a grant assigned to him by his chief or none of the above.
• No programmer can simultaneously receive a grant and assign a grant to one of his subordinates.
• No programmer can assign a grant to more than one of his subordinates
The scheme seemed to be designed perfectly — nobody would like to assign a grant to anybody since in this case he himself would not receive money. But programmers somehow discovered the plan of chief accountant and decided to make a trick to get the most money possible and share them fairly afterwards. The idea was to make such grant assignments that the total amount of grant money received is maximum possible.
You were selected to write the program which will find the optimal grants appointment.
Input
The first line of the input file contains integer N — the number of programmers in Mocrosoft company (2 ≤ N ≤ 500 000). Each programmer is assigned his unique identifier — integer number ranging from 1 to N . Bill Hates has number 1 and each programmer has the number greater then the number of his chief. The second line of the input file contains N − 1 integers, i-th of which being the number of the chief of the worker whose number is (i + 1).
Output
On the first line of the output file print the maximum possible amount of money workers can get. On the second line output the numbers of programmers that will receive grant in ascending order.
Sample Input
4 1 1 2
Sample Output
2000 3 4
题目大意:某公司有N个员工。编号1到N,除了老板(编号1)外,每个人都有一个上司。现在过年了,老板要给员工发奖金,为了避免贪污,指定了三个规则:一、每个员工要么从上司那里拿奖金,要么发奖金给下属,要么什么都不做;二、一个员工不能既从上司那里拿奖金,又给下属发奖金。三、一个员工最多给一个下属发奖金。员工们现在都知道了这些规则,想尽办法拿奖金,貌似越底层越机智?问所有员工最多能拿到多少奖金。
分析:贪心。按规则遍历一遍就行了。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 500100;
int n;
int f[maxn];
int p[maxn];
int vis[maxn];
int main() {
while(~scanf("%d", &n)) {
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= n; i++)
scanf("%d", &f[i]);
int cnt = 0;
for(int i = n; i > 1; i--) {
if(!vis[i] && !vis[f[i]]) { //这里就是规则了
vis[i] = 1;
vis[f[i]] = 1;
p[cnt++] = i;
}
}
printf("%d\n", 1000*cnt);
for(int i = cnt-1; i >= 0; i--)
printf("%d%c", p[i], i == 0 ? '\n' : ' ');
}
return 0;
}