题意:

一个王国有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的更多相关文章

  1. 【CF613D】Kingdom and its Cities 虚树+树形DP

    [CF613D]Kingdom and its Cities 题意:给你一棵树,每次询问给出k个关键点,问做多干掉多少个非关键点才能使得所有关键点两两不连通. $n,\sum k\le 10^5$ 题 ...

  2. 【CF613D】Kingdom and its Cities

    [CF613D]Kingdom and its Cities 题面 洛谷 题解 看到关键点当然是建虚树啦. 设\(f[x]\)表示以\(x\)为根的子树的答案,\(g[x]\)表示以\(x\)为根的子 ...

  3. 【CF613D】Kingdom and its Cities(虚树,动态规划)

    [CF613D]Kingdom and its Cities(虚树,动态规划) 题面 洛谷 CF 翻译洛谷上有啦 题解 每次构建虚树,首先特判无解,也就是关键点中存在父子关系. 考虑\(dp\),设\ ...

  4. CF613D Kingdom and its Cities 虚树

    传送门 $\sum k \leq 100000$虚树套路题 设$f_{i,0/1}$表示处理完$i$以及其所在子树的问题,且处理完后$i$所在子树内是否存在$1$个关键点满足它到$i$的路径上不存在任 ...

  5. CF613D:Kingdom and its Cities(树形DP,虚树)

    Description 一个王国有n座城市,城市之间由n-1条道路相连,形成一个树结构,国王决定将一些城市设为重要城市. 这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领.而非重 ...

  6. Kingdom and its Cities - CF613D

    Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in or ...

  7. [CF613D]Kingdom and its Cities

    description 题面 data range \[n, q,\sum k\le 10^5\] solution 还是虚树的练手题 \(f[0/1][u]\)表示\(u\)的子树内,\(u\)是否 ...

  8. CF613D Kingdom and its Cities 虚树 + 树形DP

    Code: #include<bits/stdc++.h> #define ll long long #define maxn 300003 #define RG register usi ...

  9. 题解 CF613D 【Kingdom and its Cities】

    考虑树形\(DP\),设\(num_x\)记录的为当\(1\)为根时,以\(x\)为子树中重要城市的个数. 那么进行分类讨论: ① 当\(num_x≠0\)时,则需将其所有满足\(num_y≠0\)的 ...

  10. CF613D Kingdom and its Cities 虚树 树形dp 贪心

    LINK:Kingdom and its Cities 发现是一个树上关键点问题 所以考虑虚树刚好也有标志\(\sum k\leq 100000\)即关键点总数的限制. 首先当k==1时 答案显然为0 ...

随机推荐

  1. Ubuntu安装 Sublime Text 及常用插件推荐

    之前一直在用 Code Blocks 这个IDE工具,可用着还是感觉不怎么好,于是在网上找到了一篇文章,上面介绍了不少IDE,我找到了Sublime Text 感觉挺不错的. 帖子地址: http:/ ...

  2. WebApplicationContext

    在Web应用中,我们会用到WebApplicationContext  用它来保存上下文信息 那么它set到ServletContext的过程是怎么样呢 1)通过WEB.XML中监听类 p.p1 { ...

  3. TCP VS UDP

    摘要:计算机网络基础 引言 网络协议是每个前端工程师都必须要掌握的知识,TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP,本文将介绍下这两者以及它们之间的区别. 一.TCP/I ...

  4. Head First 设计模式 —— 11. 组合 (Composite) 模式

    思考题 我们不仅仅要支持多个菜单,升值还要支持菜单中的菜单.你如何处理这个新的设计需求? P355 [提示]在我们的新设计中,真正需要以下三点: P354 我们需要某种属性结构,可以容纳菜单.子菜单和 ...

  5. 【SpringBoot1.x】SpringBoot1.x 配置

    SpringBoot1.x 配置 文章源码 配置文件 SpringBoot 使用一个全局的配置文件,配置文件名是固定的. application.properties.application.yml都 ...

  6. PAT天梯赛练习 L3-004 肿瘤诊断 (30分) 三维BFS

    题目分析: 可能是我的理解能力比较差,在读题的时候一直以为所有的切片是可以排列组合的,并不是按照输入顺序就定死的,那么这题就变得十分的复杂啦~~~~~,查看的题解之后发现所有的切片并没有所谓的自由组合 ...

  7. element el-table表格的vue组件二次封装(附表格高度自适应)

    基于vue的el-table表格二次封装组件方法 前言 在公司实习使用vue+element-ui框架进行前端开发,使用表格el-table较为多,有些业务逻辑比较相似,有些地方使用的重复性高,如果多 ...

  8. 【Oracle】增量备份和全库备份怎么恢复数据库

    1差异增量实验示例 1.1差异增量备份 为了演示增量备份的效果,我们在执行一次0级别的备份后,对数据库进行一些改变. 再执行一次1级别的差异增量备份: 执行完1级别的备份后再次对数据库进行更改: 再执 ...

  9. CTFHub - Web(四)

    最近又是每天忙到裂开,,,淦 xss: 反射型: 1.第一个输入框与下面Hello后的内容相同,猜测可以通过该输入,改变页面内容. 测试语句: <script>alert(1)</s ...

  10. os-Bytes环境变量劫持

    信息收集 netdiscovery -i eth0 nmap -sV -sC 192.168.43.74 -oA os-Bytes gobuster -u 192.168.43.74 -w /usr/ ...