题意:一棵树,每个节点是黑色或白色,你可以从任意节点开始进行一些操作并在任意节点结束,如果当前在$x$,那么一次操作可以是:1.走到相邻节点$y$并翻转$y$的颜色,2.翻转$x$的颜色,问把所有节点都变黑最少要多少次操作

首先当然要把黑色叶子全部删掉,这个类似拓扑排序一样做即可

然后证一个小结论:不会有一条边被经过$\gt2$次

设$(x,y)$被经过$3$次,那么操作序列为$A\Rightarrow(x\rightarrow y)\Rightarrow B\Rightarrow(y\rightarrow x)\Rightarrow C\Rightarrow(x\rightarrow y)\Rightarrow D$,我们可以把操作序列变为$A\Rightarrow C\Rightarrow\text~x\Rightarrow(x\rightarrow y)\Rightarrow\text~y\Rightarrow B\Rightarrow D$,这样等价并且没有增加操作次数

所以最优解形如:选定起点$s$和终点$t$,$s\rightarrow t$路径上的边只经过一次,其他边经过两次,并在过程中适时使用操作$2$

更进一步:存在最优解使得$s,t$都是叶子

假设起点为$x$,终点为$y$且$y$不是叶子,$z$是$y$往远离$x$方向的第一个节点,那么把原来的$(y\rightarrow z)\Rightarrow X\Rightarrow(z\rightarrow y)$变成$\text~y\Rightarrow(y\rightarrow z)\Rightarrow X$即可,同样不增加操作次数

现在考虑怎么求答案,如果$s=t$,设$d_x$为$x$的度数并记$v_x=\left[(d_x\equiv1(\bmod2),c_x=B)\text{ or }(d_x\equiv0(\bmod2),c_x=W)\right]$,那么答案是$2|E|+\sum\limits_xv_x$

当$t$移动时,$s\rightarrow t$上的边经过次数$-1$,$s\rightarrow t$这条链上$\neq t$的点(以下记这条链为$[s,t)$)的贡献也要重新计算,要加上$-\text{dis}(s,t)+\sum\limits_{x\in[s,t)}-[v_x=1]+[v_x=0]$

所以如果我们给每个点$x$一个权值$-[v_x=1]+[v_x=0]-1$,找到最小的叶子到叶子的链即可,dfs一遍统计答案即可

monochrome:单色的,黑白的

#include<stdio.h>
#include<algorithm>
using namespace std;
int h[100010],nex[200010],to[200010],M,n;
void add(int a,int b){
	M++;
	to[M]=b;
	nex[M]=h[a];
	h[a]=M;
}
int d[100010],q[100010];
bool del[100010];
char s[100010];
void topsort(){
	int head,tail,x,i;
	head=1;
	tail=0;
	for(i=1;i<=n;i++){
		if(s[i]=='B'&&d[i]==1)q[++tail]=i;
	}
	while(head<=tail){
		x=q[head++];
		del[x]=1;
		for(i=h[x];i;i=nex[i]){
			if(d[to[i]])d[to[i]]--;
			if(s[to[i]]=='B'&&d[to[i]]==1&&!del[to[i]])q[++tail]=to[i];
		}
	}
}
int f[100010],sum,mn;
int tp(int x){return(d[x]&1)^(s[x]=='W');}
int val(int x){return tp(x)==1?-2:0;}
void dfs(int fa,int x){
	sum+=(tp(x)==1)+2;
	f[x]=val(x);
	for(int i=h[x];i;i=nex[i]){
		if(to[i]!=fa&&!del[to[i]]){
			dfs(x,to[i]);
			mn=min(mn,f[x]+f[to[i]]);
			f[x]=min(f[x],f[to[i]]+val(x));
		}
	}
}
int main(){
	int i,x,y;
	scanf("%d",&n);
	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
		d[x]++;
		d[y]++;
	}
	scanf("%s",s+1);
	topsort();
	for(x=1;x<=n;x++){
		if(!del[x])break;
	}
	if(x>n)
		putchar('0');
	else{
		dfs(0,x);
		sum-=2;
		printf("%d",sum+mn);
	}
}

[ARC097F]Monochrome Cat的更多相关文章

  1. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

  2. 【AtCoder】ARC097 (C - F)题解

    C - K-th Substring 题解 找出第K大的子串,重复的不计入 这个数据范围可能有什么暴力可以艹过去吧,但是K放大的话这就是后缀自动机板子题啊= = 代码 #include <ios ...

  3. AtCoder Regular Contest 097

    AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...

  4. 基于Cat的分布式调用追踪

    Cat是美团点评出的一款APM工具,同类的产品也有不少,知名的开源产品如zipkin和pinpoint:国内收费的产品如oneapm.考虑到Cat在互联网公司的应用比较广,因此被纳入选型队列,我也有幸 ...

  5. mkdir,rmdir,cp,rm,mv,cat,touch用法

    一.mkdir新建目录 1.进入tmp目录,查看该目录下面的子目录 [root@localhost ~]# cd /tmp[root@localhost tmp]# lshsperfdata_root ...

  6. 大众点评cat系统的搭建笔记

    项目地址:https://github.com/dianping/cat 编译步骤: 这个项目比较另类,把编译需要的jar包,单独放在git分支mvn-repo里了,而且官方文档里给了一个错误的命令提 ...

  7. cat命令使用

    cat:concatenate files and print on the standard output合并文件并输出 主要用法 1.cat f1.txt,查看f1.txt文件的内容. 2.cat ...

  8. cat命令

    [cat]          合并文件和打印到标准输出 命令格式: cat [OPTION]... [FILE]... 命令功能: 拼接文件或者做标准输入输出 命令格式: cat [OPTION].. ...

  9. 查看cpu的信息cat /proc/cpuinfo

    cat /proc/cpuinfo processor : vendor_id : GenuineIntel cpu family : model : model name : Intel(R) Co ...

随机推荐

  1. poj 2762 tarjan缩点+拓扑序

    2013-09-08 10:00 var m, n :longint; t :longint; f, last :..] of longint; pre, other :..] of longint; ...

  2. Apache2.4+Tomcat7 集群

    Apache2.4+Tomcat7 集群: 1.下载并安装相对应的软件 apache下载地址:http://httpd.apache.org/ 这里使用apache2.4 tomcat下载地址:htt ...

  3. USB 3.1 與 USB Type-C 解釋

    https://tw.transcend-info.com/Support/FAQ-940 以下的內容皆來自上面這個網址. 什麼是USB 3.1? 什麼是USB 3.1? USB 3.1為USB協會制 ...

  4. java===java基础学习(2)---运算符,三元操作符,数学函数

    主要介绍运算符,和数学函数以及三元运算符: package testbotoo; public class test1 { public static void main(String[] args) ...

  5. nginx源码分析--使用GDB调试(strace、 pstack )

    nginx源码分析--使用GDB调试(strace.  pstack ) http://blog.csdn.net/scdxmoe/article/details/49070577

  6. [session篇]看源码学习session(一)

    假如你是使用过或学习过PHP,你一定觉得很简单.session只不过是$_SESSION就可以搞得,这还不简单只是对一个key-value就能工作了.我觉得可以大多数的phper都是这样的,这是语言本 ...

  7. OC 01 类和对象

    一.  定义OC的类和创建OC的对象 接下来就在OC中模拟现实生活中的情况,创建一辆车出来.首先要有一个车子类,然后再利用车子类创建车子对象 要描述OC中的类稍微麻烦一点,分2大步骤:类的声明.类的实 ...

  8. MACBOOK 总是断网怎么办

    MACBOOK 连接 wifi 老是断网.焦躁不安 看图,二个方法,第一就搞定,

  9. Leetcode 之Longest Common Prefix(34)

    这题实现起来还是挺麻烦的,就偷懒使用下库函数strtod().第二个参数表示字符中不是数字的地方,如果后面是空格,则认为其仍是数字,否则不是. bool isNumber(char *s) { cha ...

  10. JAVA中静态块、静态变量加载顺序详解

    http://blog.csdn.net/mrzhoug/article/details/51581994 一般顺序:静态块(静态变量)——>成员变量——>构造方法——>静态方法