Kingdom and its Cities - CF613D
Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in order not to lose face in front of the relatives, the King should first finish reforms in his kingdom. As the King can not wait for his daughter's marriage, reforms must be finished as soon as possible.
The kingdom currently consists of n cities. Cities are connected by n - 1 bidirectional road, such that one can get from any city to any other city. As the King had to save a lot, there is only one path between any two cities.
What is the point of the reform? The key ministries of the state should be relocated to distinct cities (we call such cities important). However, due to the fact that there is a high risk of an attack by barbarians it must be done carefully. The King has made several plans, each of which is described by a set of important cities, and now wonders what is the best plan.
Barbarians can capture some of the cities that are not important (the important ones will have enough protection for sure), after that the captured city becomes impassable. In particular, an interesting feature of the plan is the minimum number of cities that the barbarians need to capture in order to make all the important cities isolated, that is, from all important cities it would be impossible to reach any other important city.
Help the King to calculate this characteristic for each of his plan.
The first line of the input contains integer n (1 ≤ n ≤ 100 000) — the number of cities in the kingdom.
Each of the next n - 1 lines contains two distinct integers ui, vi (1 ≤ ui, vi ≤ n) — the indices of the cities connected by the i-th road. It is guaranteed that you can get from any city to any other one moving only along the existing roads.
The next line contains a single integer q (1 ≤ q ≤ 100 000) — the number of King's plans.
Each of the next q lines looks as follows: first goes number ki — the number of important cities in the King's plan, (1 ≤ ki ≤ n), then follow exactly ki space-separated pairwise distinct numbers from 1 to n — the numbers of important cities in this plan.
The sum of all ki's does't exceed 100 000.
For each plan print a single integer — the minimum number of cities that the barbarians need to capture, or print - 1 if all the barbarians' attempts to isolate important cities will not be effective.
4
1 3
2 3
4 3
4
2 1 2
3 2 3 4
3 1 2 4
4 1 2 3 4
1
-1
1
-1
7
1 2
2 3
3 4
1 5
5 6
5 7
1
4 2 4 6 7
2
In the first sample, in the first and the third King's plan barbarians can capture the city 3, and that will be enough. In the second and the fourth plans all their attempts will not be effective.
In the second sample the cities to capture are 3 and 5.
简单题意
给你一棵树,树上有n个点,然后给q个询问,每次给一些点,求最少要删掉多少点(不能删掉给出的点)才能使这些点分开(给出的总点数小于等于10^5)
胡说题解
其实我们能想到,跟答案有关的点其实就是这些点之间的LCA,其实就是要我们构造这颗虚树,然后在这个虚树上面DP
然后就是虚树的构造方法,按dfs序排序,然后动态的向虚树中加点,我们用栈来维护这颗虚树的最右边的那条链(因为我们按照dfs序排序了,加点只会跟最右边的这条链有关),每次新的点与栈顶的点求LCA,然后根据高度将栈顶的一些点弹出(自己画画图),再加入LCA和新点,这里要注意边怎么连(还是自己多画画图,分情况讨论)
将虚树构造出来后我们就可以在虚树上DP了,这个DP还比较好想,我就不多说了
傻逼错误
一开始想到求LCA,然后就开始乱搞,排序之后直接求LCA然后看这个点是不是给出的点,然后过了两个样例开开心心的交了,然后就傻逼了,WA on test3
然后各种错误,过了好久才知道要求虚树,临时学虚树怎么求,反正各种坑
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; const int maxn=;
int n,q,first[maxn],last[maxn*],next[maxn*],fa[maxn],tot,num,time[maxn],i;
int ll[maxn*][],rr[maxn*][],l[maxn],dep[maxn],s[maxn],stack[maxn];
bool flag[maxn]; void insert(int x,int y){
if(x&y==)return;
last[++tot]=y;
next[tot]=first[x];
first[x]=tot;
} bool cmp(int a,int b){
return l[a]<l[b];
} bool cmp2(int a,int b){
return dep[a]<dep[b];
} void dfs(int x,int d){
flag[x]=true;
dep[x]=d;
ll[++num][]=x;
l[x]=num;
int i=first[x];
while(i!=){
if(!flag[last[i]]){
dfs(last[i],d+);
ll[++num][]=x;
fa[last[i]]=x;
}
i=next[i];
}
} int lca(int a,int b){
int tmp;
tmp=l[b]-l[a]+;
tmp=trunc(log(tmp)/log());
if(cmp2(ll[l[a]][tmp],rr[l[b]][tmp]))tmp=ll[l[a]][tmp];
else tmp=rr[l[b]][tmp];
return tmp;
} int dp(int x){
int tmp=,num=,j=first[x];
while(j!=){
tmp+=dp(last[j]);
if(time[last[j]]==*i)++num;
j=next[j];
}
if(time[x]==*i)tmp+=num;
else
if(num>)++tmp;
else if(num==)time[x]=*i;
return tmp;
} int main(){
scanf("%d",&n);
int x,y;
for(i=;i<n;i++){
scanf("%d%d",&x,&y);
insert(x,y);
insert(y,x);
}
dfs(,);
for(i=;i<=num;i++)rr[i][]=ll[i][];
for(i=;<<(i-)<num;i++){
for(x=;num-x>=<<(i-);x++)
if(cmp2(ll[x][i-],ll[x+(<<(i-))][i-]))ll[x][i]=ll[x][i-];
else ll[x][i]=ll[x+(<<(i-))][i-];
for(x=num-(<<(i-))+;x<=num;x++)ll[x][i]=ll[x][i-];
for(x=;num-x>=<<(i-);x++)
if(cmp2(rr[x][i-],rr[x+(<<(i-))][i-]))rr[x+(<<(i-))][i]=rr[x][i-];
else rr[x+(<<(i-))][i]=rr[x+(<<(i-))][i-];
for(x=;x<=<<(i-);x++)rr[x][i]=rr[x][i-];
}
scanf("%d",&q);
bool f;
int tmp,now,lasti;
for(i=;i<=q;i++){
scanf("%d",&x);
for(y=;y<=x;y++)scanf("%d",&s[y]);
sort(s+,s++x,cmp);
f=true;y=x;
stack[]=s[];now=;
for(x=;x<=y;x++)time[s[x]]=*i;
tot=;first[s[]]=;
for(x=;x<=y;x++){
lasti=;first[s[x]]=;
tmp=lca(stack[now],s[x]);
if(time[tmp]==*i && fa[s[x]]==tmp)f=false;
if(!f)break;
while(now> && dep[stack[now]]>dep[tmp])lasti=stack[now--];
if(time[tmp]<i*-)time[tmp]=*i-,first[tmp]=;
if(stack[now]==tmp){
insert(tmp,s[x]);
stack[++now]=s[x];
}
else{
first[stack[now]]=next[first[stack[now]]];
insert(stack[now],tmp);
insert(tmp,lasti);
insert(tmp,s[x]);
stack[++now]=tmp;
stack[++now]=s[x];
}
}
if(!f)printf("-1\n");
else printf("%d\n",dp(stack[]));
}
return ;
}
AC代码
Kingdom and its Cities - 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 虚树 树形dp 贪心
LINK:Kingdom and its Cities 发现是一个树上关键点问题 所以考虑虚树刚好也有标志\(\sum k\leq 100000\)即关键点总数的限制. 首先当k==1时 答案显然为0 ...
- 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条道路相连,形成一个树结构,国王决定将一些城市设为重要城市. 这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领.而非重 ...
- [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\)的 ...
随机推荐
- 北京Uber优步司机奖励政策(9月21日~9月27日)
用户组:优步北京人民优步A组(适用于9月21日-9月27日) 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不 ...
- 限时购校验小工具&dubbo异步调用实现限
本文来自网易云社区 作者:张伟 背景 限时购是网易考拉目前比较常用的促销形式,但是前期创建一个限时购活动时需要各个BU按照指定的Excel格式进行选品提报,为了保证提报数据准确,运营需要人肉校验很多信 ...
- 游戏人工智能 读书笔记 (四) AI算法简介——Ad-Hoc 行为编程
本文内容包含以下章节: Chapter 2 AI Methods Chapter 2.1 General Notes 本书英文版: Artificial Intelligence and Games ...
- http知识点 前端
前端必须明白的http知识点 对于http的报文格式就不多细说了,做为前端开发,我们需要知道前后端联调时的请求和响应之间请求头和返回头之间的关系和每个字段中的涵意,静态文件资源在加载时我们所观察到可性 ...
- Qt-QML-自定义个自己的文本Text
好久都没有正经的更新自己的文章了,这段时间也辞职了,听了小爱的,准备买个碗,自己当老板,下面请欣赏效果图 这个界面布局就是自己是在想不到啥了,按照常规汽车导航的布局布局了一下,主要看内容哈,看看这个文 ...
- Codeforces Round #495 (Div. 2) Sonya and Matrix
正常没有正方形的限制下,值为i的点个数4i 那么从0开始遍历,第一个不为4i的值就是min(x, y) 由于对称性我们姑且令x为这个值 我们先列举n*m=t的各种情况 对于一对n, m.我们已经知道n ...
- go通过第三方库 mahonia gbk 转utf8
go get github.com/axgle/mahonia dec := mahonia.NewDecoder("GBK")ret:=dec.ConvertString(res ...
- Visual Studio Code——PHP Debug扩展
最近在使用PHP开发,使用了很多IDE,发现都不是很顺手,之前一直都在使用Sublime Text,但是作为一个爱折腾的人,当我发现VS Code以后觉得很是很适合自己的编程需要的.配置过程中遇到了一 ...
- VMWare Workstation新装CentOS 7无法联网解决办法
按照这位博主的方法成功解决:http://blog.csdn.net/deniro_li/article/details/54632949
- PAT-甲级解题目录
PAT甲级题目:点这里 pat解题列表 题号 标题 题目类型 10001 1001 A+B Format (20 分) 字符串处理 1003 1003 Emergency (25 分) 最短路径 ...