CF613D
题意:
一个王国有n座城市,城市之间由n-1条道路相连,形成一个树结构,国王决定将一些城市设为重要城市。
这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领。而非重要城市一旦被占领,这座城市就不能通行。
国王定了若干选择重要城市的计划,他想知道,对于每个计划,外敌至少要占领多少个非重要城市,才会导致重要城市之间两两不连通。如果外敌无论如何都不可能导致这种局面,输出-1
————————————————————————————————————————
首先,在洛谷交的,有一个点没有过。CF,外语网站而且很慢,不试了!
建立虚树,然后在虚树上面树形DP。
虚树,就是在做树形DP时,我们经常发现有许多点根本没用,比如这个题目中的非重要城市。我们可以把重要节点和他们的连接点(LCA)取出来重新建一棵树,这就是虚树。
方法:
首先,dfs,求出dfs序:DFN,并求出每个点的深度dep[]和LCA辅助数组f[][]
void dfs(int u,int fa)
{
f[u][0]=fa;
for(int i=1;i<20 && f[u][i-1]!=0;++i)f[u][i]=f[f[u][i-1]][i-1];
dfn[u]=++tim;dep[u]=dep[fa]+1;
for(int i=head[u];i;i=e[i].nxt)
if(e[i].v!=fa)dfs(e[i].v,u);
}
然后,对于所有的重要节点进行记录(pt[])并打标记(ispt[])
下面,将重要节点(pt[])按照DFN[]进行排序
最后,我们将pt[]中的重要节点一次取出建立虚树。
建立的虚树采用增量的方法:
把取出的点一次加入到栈里面,从栈底到栈顶的重要节点可以连成一条从根方向到叶子方向的链。
当加入当前点u时,如果栈中没用其它的点则可以直接加入点u
如果u点与栈顶的点的lca是栈顶点,则可以直接将u点加入,这样栈中的点形成一条更长的链
如果栈顶点和u点的lca不是栈顶点,那么也就是u点和栈顶点处于原树中不同的分支。我们比lca更深(比较dep[])的点依次弹出,并把相邻的点建边(这就是虚树的一部分)。然后把判断lca是否在栈中,如果不在就需要把lca加入栈中,然后把u点加入栈中。
这样所有的点都加入完成后,最后还剩余了栈中的一条链,把栈中的点一次出栈并建边,虚树完成。
注:为了有一个总的根,所以通常把1号点加入栈中。
void insert(int x)
{
if(top==0)
{
sta[top=1]=x;
return;
}
int l=lca(x,sta[top]);
if(l==sta[top])
{
sta[++top]=x;
return;
}
while(top>1 && dep[sta[top-1]]>=dep[l])
{
addage(sta[top],sta[top-1],ee,headd,jss);
addage(sta[top-1],sta[top],ee,headd,jss);
--top;
}
if(l!=sta[top])
{
addage(sta[top],l,ee,headd,jss);
addage(l,sta[top],ee,headd,jss);
sta[top]=l;
}
sta[++top]=x;
}
void build()
{
jss=0;
memset(headd,0,sizeof headd);
if(pt[1]!=1)sta[top=1]=1;
for(int i=1;i<=m;++i)
insert(pt[i]);
while(top>1)
{
addage(sta[top],sta[top-1],ee,headd,jss);
addage(sta[top-1],sta[top],ee,headd,jss);
--top;
}
}
————————————————————————————————————————

1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=1e5+10;
4 int n,q;
5 struct edge
6 {
7 int u,v,nxt;
8 }e[maxn],ee[maxn];
9 int head[maxn],headd[maxn],js,jss;
10 void addage(int u,int v,edge e[],int head[],int &js)
11 {
12 e[++js].u=u;e[js].v=v;
13 e[js].nxt=head[u];head[u]=js;
14 }
15 int dfn[maxn],tim,f[maxn][20],dep[maxn];
16 void dfs(int u,int fa)
17 {
18 f[u][0]=fa;
19 for(int i=1;i<20 && f[u][i-1]!=0;++i)f[u][i]=f[f[u][i-1]][i-1];
20 dfn[u]=++tim;dep[u]=dep[fa]+1;
21 for(int i=head[u];i;i=e[i].nxt)
22 if(e[i].v!=fa)dfs(e[i].v,u);
23 }
24 int pt[maxn],m,sta[maxn],top;
25 bool ispt[maxn];
26 bool cmp(int a,int b)
27 {
28 return dfn[a]<dfn[b];
29 }
30 int lca(int u,int v)
31 {
32 if(dep[v]>dep[u])swap(u,v);
33 for(int i=19;i>=0;--i)
34 if(dep[f[u][i]]>=dep[v])u=f[u][i];
35 if(u==v)return u;
36 for(int i=19;i>=0;--i)
37 if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
38 return f[u][0];
39 }
40 void insert(int x)
41 {
42 if(top==0)
43 {
44 sta[top=1]=x;
45 return;
46 }
47 int l=lca(x,sta[top]);
48 if(l==sta[top])
49 {
50 sta[++top]=x;
51 return;
52 }
53 while(top>1 && dep[sta[top-1]]>=dep[l])
54 {
55 addage(sta[top],sta[top-1],ee,headd,jss);
56 addage(sta[top-1],sta[top],ee,headd,jss);
57 --top;
58 }
59 if(l!=sta[top])
60 {
61 addage(sta[top],l,ee,headd,jss);
62 addage(l,sta[top],ee,headd,jss);
63 sta[top]=l;
64 }
65 sta[++top]=x;
66 }
67 void build()
68 {
69 jss=0;
70 memset(headd,0,sizeof headd);
71 if(pt[1]!=1)sta[top=1]=1;
72 for(int i=1;i<=m;++i)
73 insert(pt[i]);
74 while(top>1)
75 {
76 addage(sta[top],sta[top-1],ee,headd,jss);
77 addage(sta[top-1],sta[top],ee,headd,jss);
78 --top;
79 }
80 }
81 int ff[maxn],g[maxn];
82 void dp(int u,int fa)
83 {
84 ff[u]=g[u]=0;
85 for(int i=head[u];i;i=e[i].nxt)
86 {
87 int v=e[i].v;
88 if(v==fa)continue;
89 dp(v,u);
90 ff[u]+=ff[v];g[u]+=g[v];
91 }
92 if(!ispt[u])
93 {
94 ff[u]+=(g[u]>1);
95 g[u]=(g[u]==1);
96 }
97 else
98 {
99 ff[u]+=g[u];
100 g[u]=1;
101 }
102 }
103 int main()
104 {
105 scanf("%d",&n);
106 for(int u,v,i=1;i<n;++i)
107 {
108 scanf("%d%d",&u,&v);
109 addage(u,v,e,head,js);addage(v,u,e,head,js);
110 }
111 dfs(1,0);
112 scanf("%d",&q);
113 while(q--)
114 {
115 scanf("%d",&m);
116 memset(pt,0,sizeof pt);
117 memset(ispt,0,sizeof ispt);
118 for(int i=1;i<=m;++i)
119 {
120 scanf("%d",pt+i);
121 ispt[pt[i]]=1;
122 }
123 sort(pt+1,pt+m,cmp);
124 bool flag=1;
125 for(int i=1;i<=m;++i)
126 if(ispt[f[pt[i]][0]])flag=0;
127 if(!flag)
128 {
129 puts("-1");
130 continue;
131 }
132 build();
133 dp(1,0);
134 printf("%d\n",ff[1]);
135 }
136 return 0;
137 }
CF613D的更多相关文章
- 【CF613D】Kingdom and its Cities 虚树+树形DP
[CF613D]Kingdom and its Cities 题意:给你一棵树,每次询问给出k个关键点,问做多干掉多少个非关键点才能使得所有关键点两两不连通. $n,\sum k\le 10^5$ 题 ...
- 【CF613D】Kingdom and its Cities
[CF613D]Kingdom and its Cities 题面 洛谷 题解 看到关键点当然是建虚树啦. 设\(f[x]\)表示以\(x\)为根的子树的答案,\(g[x]\)表示以\(x\)为根的子 ...
- 【CF613D】Kingdom and its Cities(虚树,动态规划)
[CF613D]Kingdom and its Cities(虚树,动态规划) 题面 洛谷 CF 翻译洛谷上有啦 题解 每次构建虚树,首先特判无解,也就是关键点中存在父子关系. 考虑\(dp\),设\ ...
- CF613D Kingdom and its Cities 虚树
传送门 $\sum k \leq 100000$虚树套路题 设$f_{i,0/1}$表示处理完$i$以及其所在子树的问题,且处理完后$i$所在子树内是否存在$1$个关键点满足它到$i$的路径上不存在任 ...
- CF613D:Kingdom and its Cities(树形DP,虚树)
Description 一个王国有n座城市,城市之间由n-1条道路相连,形成一个树结构,国王决定将一些城市设为重要城市. 这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领.而非重 ...
- Kingdom and its Cities - CF613D
Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in or ...
- [CF613D]Kingdom and its Cities
description 题面 data range \[n, q,\sum k\le 10^5\] solution 还是虚树的练手题 \(f[0/1][u]\)表示\(u\)的子树内,\(u\)是否 ...
- CF613D Kingdom and its Cities 虚树 + 树形DP
Code: #include<bits/stdc++.h> #define ll long long #define maxn 300003 #define RG register usi ...
- 题解 CF613D 【Kingdom and its Cities】
考虑树形\(DP\),设\(num_x\)记录的为当\(1\)为根时,以\(x\)为子树中重要城市的个数. 那么进行分类讨论: ① 当\(num_x≠0\)时,则需将其所有满足\(num_y≠0\)的 ...
- CF613D Kingdom and its Cities 虚树 树形dp 贪心
LINK:Kingdom and its Cities 发现是一个树上关键点问题 所以考虑虚树刚好也有标志\(\sum k\leq 100000\)即关键点总数的限制. 首先当k==1时 答案显然为0 ...
随机推荐
- 你的项目中使用过哪些JSTL标签?
项目中主要使用了JSTL的核心标签库,包括< c:if>.< c:choose>.< c: when>.< c: otherwise>.< c:f ...
- 「Elasticsearch」ES重建索引怎么才能做到数据无缝迁移呢?
背景 众所周知,Elasticsearch是⼀个实时的分布式搜索引擎,为⽤户提供搜索服务.当我们决定存储某种数据,在创建索引的时候就需要将数据结构,即Mapping确定下来,于此同时索引的设定和很多固 ...
- POLARDB与其他关系型数据库对比
https://baijiahao.baidu.com/s?id=1610828839695075926&wfr=spider&for=pc 前言 在数据库的选择上,MySQL成为中国 ...
- three.js 中使用多线程以及性能测试
今天郭先生说一下WebWorker以及WebWorker在three.js中的应用.我们都知道Javascript是单线程的,比如执行js代码的同时UI渲染就会停止,对于多核CPU的点脑,这一点让人难 ...
- 风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击
风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击 文件包含漏洞 参考文章:https://chybeta.github.io/2017/10/08/php文件包含漏洞/ 分类 ...
- Flutter 基础组件:进度指示器
前言 Material 组件库中提供了两种进度指示器:LinearProgressIndicator和CircularProgressIndicator,它们都可以同时用于精确的进度指示和模糊的进度指 ...
- HTTP基础知识点小结
什么是http协议? http,超文本传输协议是现在互联网应用最为广泛的协议,所有的www文件都必须遵循这个标准设计这个最初的目的是为了发布和接收HTML文件.http就是web通信的基础,就是为了能 ...
- 7.prometheus之查询API
一.格式概述 二.表达式查询 2.1 Instant queries(即时查询) 2.2 范围查询 三.查询元数据 3.1 通过标签匹配器找到度量指标列表 3.2 获取标签名 3.3 查询标签值 四. ...
- Hbase Region合并
业务场景: Kafka+SparkStreaming+Hbase由于数据大量的迁移,再加上业务的改动,新增了很多表,导致rerigon总数接近4万(36个节点) 组件版本: Kafka:2.1.1 S ...
- mysqldump 的-T参数
/usr/local/mysql/bin/mysqldump -uroot -T /tmp lina xuehao 把lina数据库中的xuehao表在tmp目录下备份出来两个文件,一个是纯数据.tx ...