[ACdream 1212 New Year Bonus Grant]贪心

题意:员工之间形成一棵树,上级可以给下级发奖金,任何一个人最多可以给一个下级发,并且发了奖金后就不能接受奖金。求总共最多可以产生多少的奖金流动

思路:每次选择没有下级并且有上级的员工a,令它的上级为b,那么让b给a发奖金,之后把a和b从树中删掉,这样处理直到不存在这样的员工a。也就是说每次让叶子员工接受奖金。简单证明:对于最优情况,叶子和它的兄弟集合还有它的父亲一定有一个接受了奖金,否则可以选叶子接受从父亲发的奖金,这样比原来增加了1个奖金;假设父亲接受了奖金或者兄弟接受了奖金,那么换成自己接收奖金,奖金数目不会变少,并且一定合法。所以这样选一定是最优的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#pragma comment(linker, "/STACK:10240000")
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define X                   first
#define Y                   second
#define pb                  push_back
#define mp                  make_pair
#define all(a)              (a).begin(), (a).end()
#define fillchar(a, x)      memset(a, x, sizeof(a))
#define fillarray(a, b)     memcpy(a, b, sizeof(a))

typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#ifndef ONLINE_JUDGE
namespace Debug {
void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
}
#endif // ONLINE_JUDGE

template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}

const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;

/* -------------------------------------------------------------------------------- */

const int maxn = 5e5 + 7;

int son[maxn], fa[maxn];

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    int n, x;
    while (cin >> n) {
        for (int i = 1; i < n; i ++) {
            scanf("%d", &x);
            fa[i + 1] = x;
            son[x] ++;
        }
        queue<int> Q;
        for (int i = 1; i <= n; i ++) {
            if (son[i] == 0) Q.push(i);
        }
        vector<int> ans;
        while (!Q.empty()) {
            int H = Q.front(); Q.pop();
            if (son[fa[H]] > 0) {
                ans.pb(H);
                son[fa[H]] = 0;
                if (-- son[fa[fa[H]]] == 0) Q.push(fa[fa[H]]);
            }
        }
        cout << 1000 * ans.size() << endl;
        sort(all(ans));
        for (int i = 0; i < ans.size(); i ++) {
            printf("%d%c", ans[i], i == ans.size() - 1? ‘\n‘ : ‘ ‘);
        }
    }
    return 0;
}
时间: 2024-10-13 22:07:17

[ACdream 1212 New Year Bonus Grant]贪心的相关文章

1212 New Year Bonus Grant

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 celebratio

ZOJ 2315 New Year Bonus Grant

New Year Bonus Grant Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original ID: 231564-bit integer IO format: %lld      Java class name: Main Special Judge All programmers of Mocrosoft software company are organized in

acdream 1212(贪心)

题意:有n个人,从1到n,编号越大职位越低,然后给出了第2到第n个人的上司的编号,每个人可以有一堆小弟但只能有一个上司.年底发奖金,每个人可以从上司那得到1000元或发给某个小弟1000元,问所有人能发的奖金和最大是多少,那些人得到了奖金. 题解:直接倒着遍历一遍,把人和他的上司标记掉算作一组,看有几组. #include <stdio.h> #include <string.h> const int N = 500005; int pa[N], n, flag[N]; int m

ASC1 C New Year Bonus Grant

题意:给你一棵树,有三种规则 1)根节点不能选 2)选了这个点 它 的父亲节点和子节点都不能选. 3)一个点只能选其中的一个子节点. 问你选点的最大值 解题思路:树形DP.DP[I][1/0]表示选或不选最大的. 解题代码: 1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月21日 星期六 14时55分57秒 4 5 #include<vector> 6 #include<list> 7

SGU 195. New Year Bonus Grant

时间限制:0.75s 空间限制:4M 题意: 在一颗树(最多500000个节点)中,可以对节点染色,但是一个节点染了色后,它的父节点和兄弟节点都不能再染了,求最大的染色节点数,并输出所有染色节点. Solution: 一开始写了一个树形DP 后来看到有人说题目的输入是从上到下的...直接倒过来贪心就好了.ORZ 代码: #include <iostream> #include <cstdio> using namespace std; const int INF = 510000;

zoj 2315 New Year Bonus Grant 解题报告

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1315 题目意思:Bill Hates 是公司的老总,她管辖着很多程序员,每个程序员都有各自的上头.现在为了庆祝2013年的到来,要向这些程序员发放新年奖金.不过要遵循一些规则: 1.每个程序员要不把奖金给予她的其中一个下属,要把就等着她的上司发奖金给她. 2.每个程序员不能同时接收奖金和分发奖金. 3.如果程序员要把奖金给予她的下属,她的下属只能是一个,不能是多个.

zoj2315New Year Bonus Grant Dp

树dp吧,就是它取了 就不能取它儿子,它儿子最多有一个可以取. 然后对于每种dp[x][1] 表示 x 取了, dp[x][1] = ∑ dp[son[x][0] +1,但是如果他是1  ,他自己不能取自己,这里要注意下. dp[x][0]= max((∑dp[son[x]][0])-dp[son[x]][0] + dp[son[x]][1]; #include<iostream> #include<cstdio> #include<cstring> #include&

【树形dp】SGU 195 New Year Bonus Grant

通道 题意: 给出一棵树,根节点是1,要求根据以下要求选择最多的节点: ①不能选择1 ②若选择当前节点,那么该节点的父节点和儿子都不能选择. ③若某节点的某一个儿子节点被选择,那么该节点的其他儿子不能被选择 样例分析图: 思路:用dp[u][2]表示u节点是否被选择的最大值,则dp[u][1]=sum{dp[v][0]}+1,dp[u][0]=max(sum{dp[v][0]}  ,  sum{dp[v][0]}-min{dp[v][0]+dp[v][1]}); 代码: #include<cst

SGU195 New Year Bonus Grant

题解: 树的独立集问题... 树的独立集问题在dp上有两种写法,一种是搜索,一种是刷表. 这题是刷表 题意:给出一棵树,根节点是1,要求根据以下要求选择最多的节点: ①不能选择1 ②若选择当前节点,那么该节点的父节点和儿子都不能选择. ③若某节点的某一个儿子节点被选择,那么该节点的其他儿子不能被选择.(中文题意链接:http://blog.csdn.net/qian99/article/details/16970341) 关键是对于第3种情况. dp[u][0]表示当前点不选,dp[u][1]表