P2014 [CTSC1997] 选课

P2014 [CTSC1997] 选课 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这题的技巧:把这些没有父亲节点的点,把他们的父亲节点令为0,则可从多课树变成一棵树。

细节:由于0点是必须取的,所以m要加1

其他便是正常的背包树形dp

Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
const int N=310;
//const int M=;
//const int inf=0x3f3f3f3f;     
//const ll INF=0x3ffffffffffff;
int T,n,m,a[N],dp[N][N];
vector<int> g[N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
void dfs(int x)
{
    dp[x][1]=a[x];
    for(auto v:g[x]) dfs(v);
    for(auto v:g[x])
        for(int j=m;j;j--)
            for(int k=0;k<j;k++)
                dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[v][k]);
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    n=read(),m=read();
    m++;
    for(int i=1;i<=n;i++)
    {
        int u=read();
        a[i]=read();
        g[u].pb(i);
    }
    dfs(0);
    printf("%d",dp[0][m]);
    return 0;
}

 

posted @ 2023-03-12 19:42  QAQ啥也不会  阅读(12)  评论(0编辑  收藏  举报