• sgu 195 New Year Bonus Grant【简单贪心】


    链接:



    195. New Year Bonus Grant

    time limit per test: 1.5 sec.
    memory limit per test: 65536 KB
    input: standard
    output: standard



    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. 

    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 test(s)

    Input
    
    
    4 1 1 2 
    Output
    
    
    2000 
    3 4 


    昨晚比赛快完的时候才看懂题意,果断也没有写出来了,刚刚翻了下 cxb 去年的PPT(当时居然没有看懂大哭
    就大致 copy 了下思路和题意了。cxb 童鞋就这么放弃了实在可惜,不过人各有志了Orz

    题意:

    Mocrosoft software这个公司有N个员工。除了老板(BillHates)以外,其他每个人都有一个自己的上司。现在过年了,老板打算给员工们发奖金。为了让支出最少,现在有三个规则:

    ·Eachprogrammer may either assign a grant to one of his subordinates or have a grantassigned to him by his chief or none of the above.

     一、每个员工可以安排自己的下属拿奖金,可以等待拿自己上司给自己的奖金。也可以什么都不做。(就是说

        他给下属安排奖金后,他就不能有奖金了)

    ·Noprogrammer can simultaneously receive a grant and assign a grant to one of hissubordinates.

    二、没有哪一个程序猿可以同时接收上司给的奖金,还给自己下属安排奖金。

      (就是说他给下属安排奖金后,他就不能由奖金了!)

    ·Noprogrammer can assign a grant to more than one of his subordinates

    三、每个程序猿最多只能给自己的一个下属(要是他有下属的话)安排奖金。


    注意:每次输入的数是下一个点的父亲的编号,所以题中的输入就是一颗从上往下的树了,编写程序时从下往      上找即可。




    算法:

    贪心

    思路:

    问题转化为给一颗树染色:

    (1)每一个节点至多只有一个儿子被染色

    (2)如果某个节点被染色,那么它的所有儿子都不能染色

    (也就是一个节点如果染色了,他的父亲,兄弟,儿子都不能染色)



    样例分析图:

    code:

    Accepted 6695 KB 234 ms Visual Studio C++ 2010 763 B


    #include<stdio.h>
    #include<string.h>
    
    const int maxn = 500000+10;
    
    int p[maxn]; // 记录父亲
    int vis[maxn]; // 标记是否分到钱
    int ans[maxn]; // 记录分到钱的员工编号
    
    int main()
    {
        int n;
        while(scanf("%d", &n) != EOF)
        {
            int sum = 0;
            for(int i = 2; i <= n; i++)
            {
                scanf("%d", &p[i]);
            }
    
            memset(vis, 0, sizeof(vis)); // 初始化
            for(int i = n; i > 1; i--) // 从最底层的节点开始找
            {
                if(!vis[i] && !vis[p[i]]) //如果自己没有分到钱,而且父亲和兄弟也没有分到钱
                {
                    vis[i] = 1;
                    vis[p[i]] = 1;
                    ans[sum++] = i; // 分钱
                }
            }
            printf("%d
    ", sum*1000);
            for(int i = sum-1; i >= 0; i--)
            {
                if(i == (sum-1)) printf("%d", ans[i]);
                else printf(" %d", ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    




  • 相关阅读:
    iOS开源控件库收集
    Ruby中的几种除法
    Font
    PlaySound
    STL
    APIs
    cin and cout
    CreateWindow
    Introducing Direct2D
    VC 常用代码
  • 原文地址:https://www.cnblogs.com/freezhan/p/3219047.html
Copyright © 2020-2023  润新知