• 刷题记录(NC15033 小G有一个大树,NC51178 没有上司的舞会)


    NC15033 小G有一个大树

    题目链接

    关键点:

    1、题目的意思为找到一颗树中,删除该树中的某一个节点后,其所剩的子树的最大结点数最少

    2、要找到该结点,首先我们要先算出所有树每个节点,以该节点为跟的子树的总结点数,设为tot[i], 那么设f[i]为删除i节点后,所剩子树的最大结点数,则f[i] = max(n-tot[i], tot[k]);k为以i为跟的子树。

    3、求tot[i],首先明确tot[i] = 1+总tot[k](指i为根节点的所有子树), 我们可以利用dfs,找到根节点后,从根节点开始搜,先初始化tot[i] = 1,然后遍历其子树,加上其总结点数即可

    4、答案即为所有f[i]中的最小值

    完整代码:

    1. # include
    2. using namespace std;
    3. int n, root, ans = 1010, rans = 0;
    4. int tot[1010];
    5. int f[1010];
    6. vector<int> ve[1010];
    7. void dfs(int r)
    8. {
    9. tot[r] = 1;
    10. int maxn = 0;
    11. for (int i=0; isize(); i++)
    12. {
    13. int j = ve[r][i];
    14. dfs(j);
    15. tot[r] += tot[j];
    16. }
    17. }
    18. int main()
    19. {
    20. cin>>n;
    21. root = (1+n)*n/2;
    22. for (int i=1; i
    23. {
    24. int x, y;
    25. cin>>x>>y;
    26. ve[x].push_back(y);
    27. root-=y;
    28. }
    29. dfs(root);
    30. for (int i=1; i<=n; i++)
    31. {
    32. int maxx = 0;
    33. for (int j=0; jsize(); j++)
    34. maxx = max(maxx, tot[ve[i][j]]);
    35. f[i] = max(maxx, n-tot[i]);
    36. if (f[i]
    37. {
    38. ans = f[i];
    39. rans = i;
    40. }
    41. }
    42. cout<" "<
    43. return 0;
    44. }

    NC51178 没有上司的舞会

    题目链接

    关键点:

    1、首先明确,对于每一个开心值,只有当其父节点不选时,其子节点才存在开心值(即上司不在),那么该题就是求不连通的树的,能取到开心值的最大值

    2、对于每一个人的去或者不去,我们可以用0、1来表示,那么f[i][0],表示i不参加所能取到的最大开心值,f[i][1]表示i参加所能取到的最大开心值,

    f[i][0] += max(f[j][1], f[j][0]);j表示i的孩子,对于i不参加,那么其孩子可以选择参加或者不参加

    f[i][1] += f[j][0];对于i参加,那么j就一定不参加

    3、初始化,对于f[i][0]表示i不参加,初始化值为0,对于f[i][1]参加,初始化值为i的开心值

    4、我们搜索从跟开始搜索,答案即为根选或者不选

    完整代码:

    1. # include
    2. using namespace std;
    3. int n, root;
    4. int h[6010];
    5. vector<int> ve[6010];
    6. int f[6010][2];
    7. void dfs(int r)
    8. {
    9. f[r][0] = 0;
    10. f[r][1] = h[r];
    11. for (int i=0; isize(); i++)
    12. {
    13. int j = ve[r][i];
    14. dfs(j);
    15. f[r][0] += max(f[j][0], f[j][1]);
    16. f[r][1] += f[j][0];
    17. }
    18. }
    19. int main()
    20. {
    21. cin>>n;
    22. root = (n+1)*n/2;
    23. // cout<
    24. for (int i=1; i<=n; i++)
    25. {
    26. cin>>h[i];
    27. }
    28. int x, y;
    29. cin>>x>>y;
    30. while (x&&y)
    31. {
    32. root-=x;
    33. ve[y].push_back(x);
    34. cin>>x>>y;
    35. }
    36. // cout<
    37. dfs(root);
    38. cout<<max(f[root][0], f[root][1]);
    39. return 0;
    40. }

  • 相关阅读:
    批处理小程序的制作
    u盘上面 安装 ubuntu 系统
    牛客练习赛106 E(二分图捏)
    深度学习文本预处理利器:Tokenizer详解
    如何快速实现一个可视化看板?
    SpringBoot集成WebSocket实现在线聊天
    linux篇---修改图片权限
    PX4模块设计之二十八:RCInput模块
    代码随想录算法训练营 动态规划part16
    JVM调优工具锦囊:JDK自带工具与Arthas线上分析工具对比
  • 原文地址:https://blog.csdn.net/m0_60531106/article/details/126843389