ARC097F Monochrome Cat

原题链接:https://arc097.contest.atcoder.jp/tasks/arc097_d

Monochrome Cat

Problem Statement

There is a tree with N vertices numbered 1 through N. The i-th edge connects Vertex xi and yi. Each vertex is painted white or black. The initial color of Vertex i is represented by a letter ci. ci = W represents the vertex is white; ci = B represents the vertex is black.

A cat will walk along this tree. More specifically, she performs one of the following in one second repeatedly:

Choose a vertex that is adjacent to the vertex where she is currently, and move to that vertex. Then, invert the color of the destination vertex.
Invert the color of the vertex where she is currently.
The cat’s objective is to paint all the vertices black. She may start and end performing actions at any vertex. At least how many seconds does it takes for the cat to achieve her objective?

Constraints

1 ≤ N ≤ 105
1 ≤ xi,yi ≤ N (1 ≤ i ≤ N−1)
The given graph is a tree.
ci = W or ci = B.

Input

Input is given from Standard Input in the following format:

N
x1 y1
x2 y2
:
xN−1 yN−1
c1c2..cN

Output

Print the minimum number of seconds required to achieve the objective.

Sample Input 1

5
1 2
2 3
2 4
4 5
WBBWW

Sample Output 1

5

The objective can be achieved in five seconds, for example, as follows:

Start at Vertex 1. Change the color of Vertex 1 to black.
Move to Vertex 2, then change the color of Vertex 2 to white.
Change the color of Vertex 2 to black.
Move to Vertex 4, then change the color of Vertex 4 to black.
Move to Vertex 5, then change the color of Vertex 5 to black.

Sample Input 2

6
3 1
4 5
2 6
6 1
3 4
WWBWBB

Sample Output 2

7

Sample Input 3

1
B

Sample Output 3

0

Sample Input 4

20
2 19
5 13
6 4
15 6
12 19
13 19
3 11
8 3
3 20
16 13
7 14
3 17
7 8
10 20
11 9
8 18
8 2
10 1
6 13
WBWBWBBWWWBBWWBBBBBW

Sample Output 4

21

题目大意

给定一棵有n个节点的树,每个点有黑白两个颜色。现在有一只猫可以从任意节点开始,任意一个节点结束,要把所有节点染成黑色。

可以执行如下两种操作之一:

1.移动到相邻节点,并改变其颜色;

2.改变当前节点颜色;

求:把所有节点染成黑色所需的最少操作次数

数据范围:N<=2e5

题解

首先,显然的是,对于一个全黑的子树,我们肯定是不会访问的,那不如将所有的全黑子树砍掉,这样,叶子节点必定是白色。

考虑一个简单的情况:起点和终点是一样的,那么,我们肯定要从白点出发,遍历整棵树,回到起点,形成一个欧拉回路,整个过程的代价由每个点的度数和本身颜色决定,可以 O(n) O ( n ) 直接计算,首先每条边要被经过两次, += 总 权 值 + = 每 个 点 的 度 数 ,另外,当 +(01) mod 2=0 点 度 + 颜 色 ( 白 色 为 0 , 黑 色 为 1 )   m o d   2 = 0 时,还需要多花一个单位的代价。

那么,起点和终点不一样呢?

由于叶子节点都是白色,所以每个叶子节点都要被到达一次,那么我们的终点肯定也是一个叶子节点。这样,我们的实际路径就是欧拉回路减去了起点到终点的一条链。

对于起点到终点的链,除了终点,其他点都被少到达了一次,即颜色少改变了一次。那么,在原来欧拉回路遍历时可以直接变成黑色的点,虽然被少到达了一次,但同时也要花一个单位的代价多改一次颜色,没有减少代价;而原来遍历完是白色的点,不仅少到达了一次,还不需要花额外的代价更改颜色,减少了2个单位代价。于是,我们可以赋权后做树形 dp d p

因为上面的讨论没有考虑终点,所以在 dp d p 时,我们为了给终点留个位置,要维护两个值,一个是该点到叶子节点的路径中权值最大的,另一个是该点到一个叶子节点爸爸的路径中权值最大的。减少的代价,就是一条包含叶子节点的路径加上一条不包含叶子节点的路径不断取 max m a x 即可。

代码
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
vector<int>mmp[M];
int col[M],du[M],val[M],dp1[M],dp2[M],n,rt,tot,more;
bool allb[M];
char ch[M];
void in()
{
    int a,b;
    scanf("%d",&n);
    for(int i=1;i<n;++i)
    scanf("%d%d",&a,&b),mmp[a].push_back(b),mmp[b].push_back(a);
    scanf("%s",ch+1);
    for(int i=1;i<=n;++i)col[i]=ch[i]=='W'?0:1,rt=col[i]?rt:i;
}
void dfs(int v,int f)
{
    allb[v]=col[v];int to;
    for(int i=mmp[v].size()-1;i>=0;--i)
    {
        to=mmp[v][i];if(to==f)continue;
        dfs(to,v);
        if(!allb[to])++du[v],++du[to];
        allb[v]&=allb[to];
    }
}
void dp(int v,int f)
{
    tot+=du[v];
    if((du[v]+col[v])&1)val[v]=0;
    else val[v]=2,++tot;
    int mx1=0,mx2=0,to;bool flag=0;
    for(int i=mmp[v].size()-1;i>=0;--i)
    {
        to=mmp[v][i];if(to==f||allb[to])continue;
        flag=1;dp(to,v);
        more=max(more,max(dp1[to]+mx2+val[v],dp2[to]+mx1+val[v]));
        mx1=max(dp1[to],mx1);mx2=max(dp2[to],mx2);
    }
    dp1[v]=mx1+val[v];dp2[v]=flag?mx2+val[v]:-INT_MAX;
}
void ac()
{
    dfs(rt,0);dp(rt,0);
    if(rt)printf("%d",tot-more);
    else printf("0");
}
int main()
{
    in();ac();
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值