#虚树,树形dp#CF613D Kingdom and its Cities
分析
若两个重要城市为一条边的两个顶点显然无解
否则考虑建一棵虚树,设\(dp[x]\)表示以\(x\)为根的子树最少需要摧毁的城市数,
令\(Siz[x]\)表示\(x\)有多少个子节点需要被摧毁,
若\(x\)这个点是一个重要城市,则\(dp[x]+=Siz[x],Siz[x]=1\)
即表示\(x\)所有需要被摧毁的子节点必须摧毁
否则如果多于1个子节点需要被摧毁,那么毁掉\(x\)这座非重要城市
当然\(dp[x]\)要计算子节点的答案
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011; struct node{int y,next;}e[N<<1],E[N]; int stac[N],hs[N],a[N];
int dep[N],fat[N],siz[N],as[N],Siz[N],big[N],dfn[N],tot,Top[N],n,et=1,Et,m,dp[N],F,v[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,siz[x]=1;
for (rr int i=as[x],SIZ=-1;i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x),siz[x]+=siz[e[i].y];
if (SIZ<siz[e[i].y]) big[x]=e[i].y,SIZ=siz[e[i].y];
}
}
inline void dfs2(int x,int linp){
dfn[x]=++tot,Top[x]=linp;
if (!big[x]) return; dfs2(big[x],linp);
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=big[x]&&e[i].y!=fat[x])
dfs2(e[i].y,e[i].y);
}
inline signed lca(int x,int y){
while (Top[x]^Top[y]){
if (dep[Top[x]]<dep[Top[y]]) x^=y,y^=x,x^=y;
x=fat[Top[x]];
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
return x;
}
inline bool cmp(int x,int y){return dfn[x]<dfn[y];}
inline void add(int x,int y){E[++Et]=(node){y,hs[x]},hs[x]=Et;}
inline void Insert(int x){
if (!tot) {stac[++tot]=x; return;}
rr int Lca=lca(x,stac[tot]);
while (tot>1&&dep[Lca]<dep[stac[tot-1]]) add(stac[tot-1],stac[tot]),--tot;
if (dep[Lca]<dep[stac[tot]]) add(Lca,stac[tot]),--tot;
if (stac[tot]!=Lca) stac[++tot]=Lca; stac[++tot]=x;
}
inline void dfs(int x){
dp[x]=Siz[x]=0;
for (rr int i=hs[x];i;i=E[i].next)
dfs(E[i].y),dp[x]+=dp[E[i].y],Siz[x]+=Siz[E[i].y];
hs[x]=0;
if (v[x]) dp[x]+=Siz[x],Siz[x]=1;
else if (Siz[x]>1) ++dp[x],Siz[x]=0;
}
signed main(){
n=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et;
e[++et]=(node){x,as[y]},as[y]=et;
}
dfs1(1,0),dfs2(1,1);
for (rr int Q=iut();Q;--Q){
m=iut(),tot=Et=F=0,a[++m]=1;
for (rr int i=1;i<m;++i) v[a[i]=iut()]=1;
for (rr int i=1;i<m;++i)
if (v[fat[a[i]]]){
printf("-1\n");
F=1;
break;
}
if (!F){
sort(a+1,a+1+m,cmp),m=unique(a+1,a+1+m)-a-1;
for (rr int i=1;i<=m;++i) Insert(a[i]);
for (;tot>1;--tot) add(stac[tot-1],stac[tot]);
dfs(1);
printf("%d\n",dp[1]);
}
for (rr int i=1;i<=m;++i) v[a[i]]=0;
}
return 0;
}
#虚树,树形dp#CF613D Kingdom and its Cities的更多相关文章
- 【BZOJ-3572】世界树 虚树 + 树形DP
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1084 Solved: 611[Submit][Status ...
- 【BZOJ-2286】消耗战 虚树 + 树形DP
2286: [Sdoi2011消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2120 Solved: 752[Submit][Status] ...
- bzoj 2286(虚树+树形dp) 虚树模板
树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5002 Sol ...
- BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca
BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...
- BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP
题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...
- [WC2018]通道——边分治+虚树+树形DP
题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...
- 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)
传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...
- 【CF613D】Kingdom and its Cities 虚树+树形DP
[CF613D]Kingdom and its Cities 题意:给你一棵树,每次询问给出k个关键点,问做多干掉多少个非关键点才能使得所有关键点两两不连通. $n,\sum k\le 10^5$ 题 ...
- CF613D Kingdom and its Cities 虚树 树形dp 贪心
LINK:Kingdom and its Cities 发现是一个树上关键点问题 所以考虑虚树刚好也有标志\(\sum k\leq 100000\)即关键点总数的限制. 首先当k==1时 答案显然为0 ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
随机推荐
- Flutter学习(PV)——概览
接触flutter有一段时间了,趁着刚过完年有点时间,记录一些有用的东西,一方面给自己备忘,另一方面也希望能帮到有需要的人~ 一.什么是flutter Flutter is Google's UI t ...
- yum源配置脚本
# yum源配置脚本 #!/bin/bash mkdir /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bac ...
- iOS 面向对象与类
至于未来会怎样,要走下去才知道反正路还很长,天总会亮. 1. 面向对象 1.1 什么是面向对象(OOP) 面向对象 Object Oriented Programming.在软件开发中,我们虽然用的是 ...
- C C++内功心法-基础篇
大家好,今天给大家讲讲C C++的一些基础语法,小编整理了一些简单入门基础知识,对于我们编程也有很多的帮助. C++ cin C++中的cin是一个 istream对象,从标准输入中读取数据,在ios ...
- 基于 Nebula Graph 构建百亿关系知识图谱实践
本文首发于 Nebula Graph Community 公众号 一.项目背景 微澜是一款用于查询技术.行业.企业.科研机构.学科及其关系的知识图谱应用,其中包含着百亿级的关系和数十亿级的实体,为了使 ...
- SpringCloud Nacos
1.Nacos简介 SpringCloud Alibaba 由来: 因为原先Spring Cloud 的许多组件都是对Netflix 公司的各种框架进行封装, 然后因为Netflix公司对后续更新的各 ...
- STM32 LwIP学习过程问题总结(一):LwIP ping不通,抓包发现ICMP校验和为0x0000
一.问题 今天在将之前的STM32 LwIP1.4.1版本程序移植到2.1.2版本上时,发现ping不同,但是开发板有ICMP回复包,黄颜色警告checksum为0x0000.说明LwIP移植应该是没 ...
- SourceTree 合并DEV分支到master
SourceTree 合并DEV分支到master 1 切换到master分支 2 右键dev分支,选择 合并dev至当前分支 3 提交代码
- python3 Crypto模块实例解析
一 模块简介 1.简介 python的Crypto模块是安全hash函数(例如SHA256 和RIPEMD160)以及各种主流的加解密算法的((AES, DES, RSA, ElGamal等)的集合. ...
- Base MYSQL Database create stored procedures resolve the Delimiter error
Base MYSQL Database create stored procedures resolve the Delimiter error, It must be created using a ...