• luogu1273 有限电视网


    题目大意

      有一棵有根树,每个结点有一个收益,每条边有一个花费。如果要选择一个叶子结点,则根节点到该叶子结点的路径上的所有结点都必须被选择。求当总收益大于等于总花费的情况下,最多能选择多少个叶子结点。

    思路

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cassert>
    using namespace std;
    
    const int MAX_NODE = 3010, MAX_EDGE = MAX_NODE, MINF = 0xcfcfcfcf;
    int TotNode, TotLeaf;
    
    struct Node;
    struct Edge;
    
    struct Node
    {
        Edge *Head;
        int DP[MAX_NODE];
        int Val;
        int LeafCnt;
    }_nodes[MAX_NODE];
    
    struct Edge
    {
        Node *To;
        Edge *Next;
        int Cost;
    }_edges[MAX_EDGE];
    int _eCount;
    
    void AddEdge(Node *from, Node *to, int w)
    {
        Edge *e = _edges + ++_eCount;
        e->To = to;
        e->Cost = w;
        e->Next = from->Head;
        from->Head = e;
    }
    
    void Dfs(Node *cur)
    {
        memset(cur->DP, MINF, sizeof(cur->DP));
        cur->DP[0] = 0;
        if (cur - _nodes > TotNode - TotLeaf)
        {
            assert(!cur->Head);
            cur->DP[1] = cur->Val;
            cur->LeafCnt = 1;
            return;
        }
        for (Edge *e = cur->Head; e; e = e->Next)
        {
            Dfs(e->To);
            cur->LeafCnt += e->To->LeafCnt;
        }
        for (Edge *e = cur->Head; e; e = e->Next)
            for (int j = cur->LeafCnt; j >= 1; j--)
                for (int k = 1; k <= min(j, e->To->LeafCnt); k++)
                    cur->DP[j] = max(cur->DP[j], cur->DP[j - k] + e->To->DP[k] - e->Cost);
    }
    
    int main()
    {
        scanf("%d%d", &TotNode, &TotLeaf);
        for (int i = 1; i <= TotNode - TotLeaf; i++)
        {
            int totOut, to, w;
            scanf("%d", &totOut);
            for (int j = 1; j <= totOut; j++)
            {
                scanf("%d%d", &to, &w);
                AddEdge(_nodes + i, _nodes + to, w);
            }
        }
        for (int i = TotNode - TotLeaf + 1; i <= TotNode; i++)
            scanf("%d", &_nodes[i].Val);
        Dfs(_nodes + 1);
        for (int j = TotLeaf; j >= 0; j--)
        {
            if (_nodes[1].DP[j] >= 0)
            {
                printf("%d
    ", j);
                return 0;
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    Emqx启用Redis认证
    写在2021末
    如何让 Spring Security 「少管闲事」
    泛型就这么简单
    Spring Boot 对多线程支持提高程序执行效率
    Java桌面应用JavaFX01Hello World
    PostgreSQL实现Oracle merge into功能
    超大JSON文件解析方案(Java)
    记一次IDEA搭建Spring源码阅读环境
    Oracle转PostgreSQL之start with / connect by
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9427610.html
Copyright © 2020-2023  润新知