zoukankan      html  css  js  c++  java
  • Codeforces 1118F1 Tree Cutting (Easy Version) (简单树形DP)

    <题目链接>

    题目大意:

    给定一棵树,树上的点有0,1,2三中情况,0代表该点无色。现在需要你将这棵树割掉一些边,使得割掉每条边分割成的两部分均最多只含有一种颜色的点,即分割后的两部分不能1,2点夹杂(0的点数可以任意),问你最多能有几条这样的割点。

    解题分析:

    dfs求解出所有点以自己为根的子树 i 中1,2,节点的个数num1,num2,然后根据母树与子树之间的num1,num2值做差,能够得到 i 的另一部分的1,2,节点个数,然后再判断这两部分是否符合条件即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N int(3e5+7)
     5 #define rep(i,s,t) for(int i=s;i<=t;i++)
     6 #define pb push_back
     7 int n;
     8 int col[N],num1[N],num2[N];
     9 vector<int>G[N];
    10 
    11 void dfs(int u,int pre){
    12     if(col[u]==1)num1[u]=1;
    13     if(col[u]==2)num2[u]=1;
    14     for(int i=0;i<G[u].size();i++){
    15         int v=G[u][i];
    16         if(v==pre)continue;
    17         dfs(v,u);
    18         num1[u]+=num1[v],num2[u]+=num2[v];       //得到每个以u为根的子树的1、2节点的个数
    19     }
    20 }
    21 
    22 int main(){
    23     scanf("%d",&n);
    24     for(int i=1;i<=n;i++)scanf("%d",&col[i]);
    25     for(int i=1;i<n;i++){
    26         int u,v;scanf("%d%d",&u,&v);
    27         G[u].pb(v);G[v].pb(u);        
    28     }
    29     dfs(1,-1);
    30     int ans=0;
    31     for(int i=2;i<=n;i++){      //以1节点为整棵树的根节点
    32         int x=num1[1]-num1[i];
    33         int y=num2[1]-num2[i];
    34         if(num1[i]&&num2[i])continue;  //如果以i为根的子树含有两种颜色,它与它pre节点的边即使断开,也不符合
    35         else if(x==0||y==0)ans++;     //在上一句的情况下,如果整棵树以i为根的1、2节点个数有一个为0,那么将i与其pre节点之间的边断开成的两部分是符合条件的
    36     }
    37     printf("%d
    ",ans);
    38 }

    2019-02-22

  • 相关阅读:
    【实验吧】CTF_Web_登录一下好吗?
    各种常用数字格式化
    .Net 4.0 (2)
    springBoot+springSecurity 数据库动态管理用户、角色、权限
    springboot+mybatis+SpringSecurity 实现用户角色数据库管理
    Spring boot中Redis的使用
    spring data jpa的使用
    如何优雅的使用mybatis
    WebJars
    mvn打包的POm文件
  • 原文地址:https://www.cnblogs.com/00isok/p/10417040.html
Copyright © 2011-2022 走看看