http://codeforces.com/problemset/problem/613/D

题意:

给出n个点的树,有q个询问,每次询问给出k个重要的点,问至少删掉多少个非重要的点,使得这个重要的点都不连通。

首先对于一个询问,无解的情况肯定是有两个相邻的重要点,直接特判就行。

对于其他情况,进行一次tree dp。

如果当前点为非重要点,且它的子树中有至少两个重要点,那么将这个点删掉。

如果当前点为重要点,对于其中一个儿子,如果这个儿子的子树中有重要点,那么将这个点的儿子删掉。

但是询问太多,就要用到虚树了。

考虑每次询问,有实际作用的点只有:重要点以及这些点的lca。那么我们对于每个询问,都建一个新图,只把这些点抽出来tree dp。

注意在新图中相邻的点不一定在原图中相邻。

关于建新图,当我们把倍增lca预处理好之后,原图就没有用了,所以我们把链式前向星清空,然后就是普通建图姿势了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>using namespace std;const int maxn=100005,maxd=18,inf=0x3f3f3f3f;int n,head[maxn],cnt,st[maxn],ed[maxn],depth[maxn],fa[maxn][maxd];
int clo,sta[maxn],f[maxn][2];bool imp[maxn];struct _edge
{int v,next;
}g[maxn<<1];void add(int u,int v)
{g[cnt]=(_edge){v,head[u]};head[u]=cnt++;
}void dfs(int x)
{st[x]=++clo;for(int i=head[x];~i;i=g[i].next)if(g[i].v!=fa[x][0]){fa[g[i].v][0]=x;depth[g[i].v]=depth[x]+1;dfs(g[i].v);}ed[x]=clo;
}int getlca(int u,int v)
{if(depth[u]<depth[v])swap(u,v);for(int i=maxd-1;i>=0;i--)if(depth[fa[u][i]]>=depth[v])u=fa[u][i];for(int i=maxd-1;i>=0;i--)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];return u==v ? u : fa[u][0];
}int node[maxn];int dp(int x)
{int tot=0,ans=0;for(int i=head[x];~i;i=g[i].next){ans+=dp(g[i].v);tot+=node[g[i].v];}if(imp[x]){ans+=tot;node[x]=1;}else{ans+= (tot>1);node[x]= (tot==1);}return ans;}bool cmp(int a,int b)
{return st[a]<st[b];
}int main()
{scanf("%d",&n);for(int i=0;i<maxn;i++){head[i]=-1;}cnt=clo=0;for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);x--;y--;add(x,y);add(y,x);}depth[0]=0;fa[0][0]=0;dfs(0);for(int j=1;j<maxd;j++)for(int i=0;i<n;i++){fa[i][j]=fa[fa[i][j-1]][j-1];}int T;scanf("%d",&T);while(T--){vector<int> v;int m;scanf("%d",&m);for(int i=0;i<m;i++){int x;scanf("%d",&x);x--;v.push_back(x);imp[x]=1;}bool flag = 0;for(int i = 0; i < v.size(); i++)if(fa[v[i]][0] != v[i] && imp[fa[v[i]][0]]) {flag = 1;break;}if(flag) {printf("-1\n");for(int i = 0; i < v.size(); i++) imp[v[i]] = 0;continue;}sort(v.begin(),v.end(),cmp);for(int i=1;i<m;i++){v.push_back(getlca(v[i-1],v[i]));}sort(v.begin(),v.end(),cmp);v.resize(unique(v.begin(),v.end())-v.begin());int top=0;cnt=0;for(int i=0;i<v.size();i++){int x=v[i];head[x]=-1;for(;top&&!(st[sta[top]]<=st[x]&&st[x]<=ed[sta[top]]);top--);if(top)add(sta[top],x);sta[++top]=x;}printf("%d\n",dp(v[0]));for(int i = 0; i < v.size(); i++) imp[v[i]] = 0;}}

【Codeforces613D】Kingdom and its Cities【虚树】【Tree DP】倍增lca相关推荐

  1. CodeForces - 613D Kingdom and its Cities(虚树+贪心)

    题目链接:点击查看 题目大意:给出一棵 n 个结点组成的树,有多组询问,每组询问给出 k 个点,现在可以删除不同于 k 个节点的 m 个节点,使得这 k 个节点两两不连通,要求最小化 m ,如果不可能 ...

  2. 2019长沙学院新生赛(A水,B水,C(整除分块),D水,E(巧数学),F(二分+bfs),H(换根dp),I(线段树)J(dp+倍增+lca))

    A-XOR SUM 通过简单观察得知连续四个数的异或值就是等于0,暴力找出左区间和右区间就可以了,最多跑四个单位 0^1^2^3==0   4^5^6^7=0 #include<bits/std ...

  3. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  4. BZOJ3572 [Hnoi2014]世界树 【虚树 + 树形dp】

    题目 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石. ...

  5. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问, 每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接. 最少的边权和是多少. (n<=250000,sigma(ki)&l ...

  6. BZOJ5419[Noi2018]情报中心——线段树合并+虚树+树形DP

    题目链接: [NOI2018]情报中心 题目大意:给出一棵n个节点的树,边有非负边权,并给出m条链,对于每条链有一个代价,要求选出两条有公共边的链使两条链的并的边权和-两条链的代价和最大. 花了一天的 ...

  7. bzoj3572 [HNOI2014]世界树 虚树 +乱dp

    这个题有Σ的条件,肯定还是用log结构求询问点相关了 但这个题是点之间的距离关系,所以本来想用中点来代替原来的lca,但中点的个数不满足任何单调性,而且个数也不是n个 所以还是要用lca,所以考虑lc ...

  8. bzoj 3611: [Heoi2014]大工程(虚树+树形DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MB Submit: 1697  Solved: 718 [Submit][Stat ...

  9. loj 6184 无心行挽 虚树+DP+倍增

    题目分析 首先,这题肯定要用虚树. 接下来,你会发现,使得f(u)f(u)f(u)最大的uuu,可能存在于三个位置: 虚树上 虚树上一个没有关键点的子树中 虚树上的一条边中 于是便分类讨论. 对于第一 ...

  10. P2495 [SDOI2011]消耗战-虚树+树形dp

    https://www.luogu.com.cn/problem/P2495 虚树:当我们在解决树形dp的问题的时候,题目中会给出一些询问,询问涉及的关键节点不多,并保证总的点数规模的时候,我们就可以 ...

最新文章

  1. 突破微信小程序五层层级限制的解决方案
  2. 一起学WPF系列(2):第一个WPF应用程序
  3. 消灭Bug!推荐7款优秀的开源Bug跟踪工具
  4. 【c++】 类与对象
  5. IO多路复用概念介绍
  6. OpenCASCADE:写IGES
  7. 用ABAP进行HTTP编程如何获取交互中的错误明细
  8. Hadoop学习之pig
  9. js调用python接口_JavaScript如何调用Python后端服务
  10. Qt学习笔记-国际化
  11. The Process class relies on proc_open, which is not available on your PHP installation.
  12. 浅谈 js 字符串之神奇的转义
  13. 决策树的sklearn实现及其GraphViz可视化
  14. android 阅读器字体,为 Android 换上任意喜欢的字体,你可以试试这个 Magisk 模块...
  15. linux添加变色龙引导,变色龙引导工具下载
  16. 30岁 android,90后30岁倒计时
  17. PyQt5-UI界面控件布局实战-界面水平,竖直、网格混合布局(三)
  18. 关于新加坡的身份证与电话号码验证
  19. iOS8新功能新特性
  20. 【转】SPARC处理器30年沉浮

热门文章

  1. 呆萌却实际可怕的动物:蛇鹫会踢腿 大熊猫攻击凶猛
  2. POJ 1606 Jugs
  3. web前端整套面试题(二)--今日头条面试题
  4. 情感分析之PMI互信息
  5. iOS App跟小程序之间跳转
  6. 英语影视台词---无敌破坏王2大脑互联网(2)(我完全被震惊了)
  7. JDK+JAVA+TOMCAT+MAVEN+IDEA的安装配置以及新建项目
  8. CITA架构与云计算服务
  9. 梯度消失\梯度爆炸(Vanishing/exploding gradients)与解决方案
  10. python中如何打开csv文件_Python对CSV文件的处理