zoukankan      html  css  js  c++  java
  • [codevs1380]没有上司的舞会([BZOJ2060][Usaco2010 Nov]Visiting Cows 拜访奶牛)

    [codevs1380]没有上司的舞会

    试题描述

    Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。

    输入

    第一行一个整数N。(1<=N<=6000)
    接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
    接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
    最后一行输入0,0。

    输出

    输出最大的快乐指数。

    输入示例

    7
    1
    1
    1
    1
    1
    1
    1
    1 3
    2 3
    6 4
    7 4
    4 5
    3 5
    0 0

    输出示例

    5

    数据规模及约定

    见“输入

    题解

    我来刷水了!

    把每个人看成一个节点。设 f[0][i] 表示对于子树 i,不选择 i 节点能够得到的最大值;f[1][i] 表示选择 i 节点能够得到的最大值。那么,

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = Getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
        return x * f;
    }
    
    #define maxn 6010
    #define maxm 12010
    int n, m, head[maxn], next[maxm], to[maxm], val[maxn];
    
    void AddEdge(int a, int b) {
    	to[++m] = b; next[m] = head[a]; head[a] = m;
    	swap(a, b);
    	to[++m] = b; next[m] = head[a]; head[a] = m;
    	return ;
    }
    
    int f[2][maxn];
    void dp(int u, int fa) {
    	f[0][u] = 0; f[1][u] = val[u];
    	for(int e = head[u]; e; e = next[e]) if(to[e] != fa) {
    		dp(to[e], u);
    		f[0][u] += max(f[0][to[e]], f[1][to[e]]);
    		f[1][u] += f[0][to[e]];
    	}
    	return ;
    }
    
    int main() {
    	n = read();
    	for(int i = 1; i <= n; i++) val[i] = read();
    	for(int i = 1; i < n; i++) {
    		int a = read(), b = read();
    		AddEdge(a, b);
    	}
    	read(); read();
    	
    	dp(1, 0);
    	
    	printf("%d
    ", max(f[0][1], f[1][1]));
    	
    	return 0;
    }
    

    双倍经验:BZOJ2060,改改输入。

  • 相关阅读:
    css知识点
    javascript 中闭包
    javascript 继承方法总结
    css滚动滚轮事件
    关于闭包的总结
    xpth xslt
    好的js函数
    自动化测试实施(4)
    自动化测试实施(5)
    自动化测试实施(3)
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5988244.html
Copyright © 2011-2022 走看看