ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

COCI2020.11 T5

2021-06-20 12:04:59  阅读:194  来源: 互联网

标签:xor min int rep T5 起始 yny COCI2020.11


状态很显然,设\(f[x][i][j]\)表示在以\(x\)为根的子树内有\(i\)个起始点,当除了点\(x\)的其它点都被点亮且点\(x\)上的灯的状态为\(j\)时路径长度的\(min\)

接下来考虑转移(本篇参考了Tommy0103的博客,算是那篇博客的一篇补充)

若当前\(x\)内没有一个起始点,则其子树内也没有起始点,转移也非常显然,就是看下如何同时满足自己的状态的同时满足所有儿子为1

\(f[x][0][j]=min(f[x][0][j]+f[v][0][1]+4,f[x][0][j \ xor\ 1]+f[v][0][0]+2)\)

若当前\(x\)内有一个起始点,情况变得有点麻烦了起来,但也就是个分类讨论看看\(x\)是不是起始点

\(f[x][1][j]=min(min(f[x][0][j \ xor \ 1]+f[v][1][1]+1,f[x][0][j]+f[v][1][0]+3),min(f[x][1][j \ xor \ 1]+f[v][0][0]+2,f[x][1][j]+f[v][0][1]+4))\)

前半截是要从\(v\)开始走,后半截是要从\(x\)开始走

上两种情况的重点在于因为\(x\)内没有包含两个起始点,所以无论怎么走一定会回到\(x\),下面来看最复杂的情况

考虑\(x\)和当前要转移的子树都有\(1\)个起始点

因为起点重点反过来路径一样,所以考虑子树中的那个为终点,则易有转移

\(min(f[x][1][j^1]+f[v][1][0]+2,f[x][1][j]+f[v][1][1])\)

因为它没必要走回去所以不必\(+4\),这里非常重要

剩下的就一样了,两种情况转移分别为

\(min(f[v][0][0]+f[x][2][j \ xor \ 1]+2,f[v][0][1]+f[x][2][j]+4)\)

\(min(f[v][2][0]+g[0][j \ xor \ 1]+2,f[v][2][1]+g[0][j]+4)\)

最后再把\(x\)做为起始点的情况转移一下就行了

code

#include <bits/stdc++.h>
#define rep(a,b,c) for(int a=(b);a<=(c);a++)
#define per(a,b,c) for(int a=(b);a>=(c);a--)
#define repe(a) for(int yny=head[a],v;yny&&(v=e[yny].v);yny=e[yny].u)
using namespace std;
const int N=5e5+5;
struct Edge {
	int u,v;
}e[N*2];
int head[N],ecnt;
inline void adde(int u,int v) { e[++ecnt].v=v;e[ecnt].u=head[u];head[u]=ecnt; }
inline void add(int u,int v) { adde(u,v); adde(v,u); }
inline int min(int a,int b,int c) { return min(a,min(b,c)); }
int f[N][3][2],sz[N];
char s[N];
int n,a,b;
inline void dfs(int x,int fa) {
	int chk=(s[x]=='1');
	sz[x]=(chk^1);
	rep(i,0,2) rep(j,0,1) f[x][i][j]=(4*n+1);
	f[x][0][chk]=0; f[x][1][chk^1]=1;
	int g[3][2];
	repe(x) if(v!=fa) {
		dfs(v,x);
		sz[x]+=sz[v];
		if(!sz[v]) continue;
		rep(i,0,2) rep(j,0,1) g[i][j]=f[x][i][j];
		rep(j,0,1) {
			f[x][0][j]=min(f[v][0][0]+g[0][j^1]+2,f[v][0][1]+g[0][j]+4);
			f[x][1][j]=min(min(f[v][0][0]+g[1][j^1]+2,f[v][0][1]+g[1][j]+4),min(f[v][1][1]+g[0][j^1]+1,f[v][1][0]+g[0][j]+3));
			f[x][2][j]=min(min(f[v][1][0]+g[1][j^1]+2,f[v][1][1]+g[1][j]),min(f[v][0][0]+g[2][j^1]+2,f[v][0][1]+g[2][j]+4),min(f[v][2][0]+g[0][j^1]+2,f[v][2][1]+g[0][j]+4));
		}
	}
	rep(i,0,2) rep(j,0,1) g[i][j]=f[x][i][j];
	rep(j,0,1) {
		f[x][1][j]=min(f[x][1][j],g[0][j^1]+1);
		f[x][2][j]=min(f[x][2][j],g[1][j]);
	}
}
int main() {
	scanf("%d",&n);
	scanf("%s",s+1);
	rep(i,2,n) scanf("%d %d",&a,&b),add(a,b);
	rep(i,1,n) if(s[i]=='0') {
		dfs(i,0);
		printf("%d\n",f[i][2][1]);
		return 0;
	}
	puts("0");
}

标签:xor,min,int,rep,T5,起始,yny,COCI2020.11
来源: https://www.cnblogs.com/A-Dance-of-Fire-and-Ice/p/14906404.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有