码迷,mamicode.com
首页 > 其他好文 > 详细

白魔法师

时间:2020-05-19 00:51:34      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:isp   ack   src   sed   list   turn   pen   main   inline   

对于这个题目,我的做法是换根dp, 因为可以选择将某一个点染成白色(不论之前的点是黑是白) , 做法如下:

将每个点当成根节点, 然后将根节点染成白色, 完全符合题意;;

首先dfs一下, 自底向上,求出每一个点在子树内的白色连通块大小。

然后从上到下开始算对孩子节点的贡献::

如果当前点是黑色, 那么对儿子节点肯定没有贡献 , 因为上面的所有节点都被这个黑色节点隔开了,下面的节点不能和上面的节点连接;

如果当前节点是白色 :

        如果孩子节点是黑色, 那么在第一次dfs的时候,孩子节点肯定对这个父亲节点没有贡献, 那么就当前节点对孩子节点直接传递下去dp[u]

        如果孩子节点是白色, 那么在第一次dfs的时候,孩子节点肯定对这个父亲节点有贡献, 那么当前节点对孩子节点的贡献就是dp[u] - dp[x] ,剪掉孩子的贡献, 避免重复计算

技术图片
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
int in()
{
  int x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == -) f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
int col[N] , dp[N]  , n ;
vector<int> v[N] ;
void dfs(int u , int f)
{
  dp[u] = col[u] ;
  for(auto x : v[u])
   {
     if(x == f) continue ;
     dfs(x , u) ;
     if(col[x]) dp[u] += dp[x] ;
   }
  return ;
}
int ans = 0 ;
void dfs1(int u , int f , int sum)
{
//  cout << u << " " << f << " " << sum << " " << dp[u] << endl ;
  dp[u] = dp[u] + sum + (col[u] == 0);
  ans = max(ans , dp[u]) ;
  for(auto x : v[u])
   {
     if(x == f) continue ;
     dfs1(x , u , (col[u] ?(col[x] ? dp[u] - dp[x] : dp[u]):0)) ;
   }
}
int main()
{
  n = in() ;
  string s ;
  cin >> s ;
  s = " " + s ;
  for(int i = 1 ; i <= n ;i ++ ) col[i] = s[i] == W ;
  for(int i = 1; i < n ;i ++ )
   {
     int a = in() , b = in() ;
     v[a].push_back(b) , v[b].push_back(a) ;
   }
  dfs(1 , 0) ;
  dfs1(1 ,0 ,  0) ;
  cout << ans << endl ;
  return 0 ;
}
/*
13
WBWWBBBBBWWWB
1 2
1 3
2 4
2 5
3 6
3 7
5 8
8 10
8 11
7 9
9 12
9 13

4
*/
View Code

 

白魔法师

标签:isp   ack   src   sed   list   turn   pen   main   inline   

原文地址:https://www.cnblogs.com/spnooyseed/p/12913760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!