CF613D Kingdom and its Cities 虚树
$\sum k \leq 100000$虚树套路题
设$f_{i,0/1}$表示处理完$i$以及其所在子树的问题,且处理完后$i$所在子树内是否存在$1$个关键点满足它到$i$的路径上不存在任何点被封的最小代价。
转移考虑$i$是否是关键点以及是否封$i$号点。
注意判断相邻两个点同时是关键点的情况。同时需要注意:如果虚树上两个点不相邻,可以封这两个点之间的点。
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
struct Edge{
int end , upEd;
}Ed[MAXN << ] , newEd[MAXN];
] , newHead[MAXN] , s[MAXN] , dfn[MAXN] , num[MAXN] , dp[MAXN][] , dep[MAXN];
int N , headS , cntEd , cntNewEd , ts , cnt;
bool imp[MAXN];
inline void addEd(Edge* Ed , int* head , int& cntEd , int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
void init(int now , int fa){
dfn[now] = ++ts;
dep[now] = dep[fa] + ;
jump[now][] = fa;
; jump[now][i - ] ; ++i)
jump[now][i] = jump[jump[now][i - ]][i - ];
for(int i = head[now] ; i ; i = Ed[i].upEd)
if(Ed[i].end != fa)
init(Ed[i].end , now);
}
inline int jumpToLCA(int x , int y){
if(dep[x] < dep[y])
swap(x , y);
; i >= ; --i)
<< i) >= dep[y])
x = jump[x][i];
if(x == y)
return x;
; i >= ; --i)
if(jump[x][i] != jump[y][i]){
x = jump[x][i];
y = jump[y][i];
}
];
}
inline void create(){
imp[] = ;
dp[][] = dp[][] = ;
; i <= cnt ; ++i){
imp[num[i]] = ;
dp[num[i]][] = ;
dp[num[i]][] = N + ;
}
; i <= cnt ; ++i)
if(!headS)
s[++headS] = num[i];
else{
int t = jumpToLCA(s[headS] , num[i]);
if(t != s[headS]){
]] > dep[t]){
addEd(newEd , newHead , cntNewEd , s[headS - ] , s[headS]);
--headS;
}
addEd(newEd , newHead , cntNewEd , t , s[headS]);
if(s[--headS] != t)
s[++headS] = t;
}
s[++headS] = num[i];
}
){
addEd(newEd , newHead , cntNewEd , s[headS - ] , s[headS]);
--headS;
}
)
addEd(newEd , newHead , cntNewEd , , s[headS]);
--headS;
}
void dfs(int now){
;
for(int i = newHead[now] ; i ; i = newEd[i].upEd){
int t = newEd[i].end;
dfs(t);
if(imp[now])
] == now)
dp[now][] += dp[t][];
else
dp[now][] += min(dp[t][] , dp[t][] + );
else{
] == now)
dp[now][] = min(sum + dp[t][] , dp[now][] + dp[t][]);
else
dp[now][] = min(sum + dp[t][] , dp[now][] + min(dp[t][] , dp[t][] + ));
] == now)
sum += dp[t][];
else
sum += min(dp[t][] , dp[t][] + );
}
] > N)
dp[now][] = N + ;
)
sum = N + ;
}
sum = ;
for(int i = newHead[now] ; i ; i = newEd[i].upEd){
int t = newEd[i].end;
if(!imp[now]){
sum += min(dp[t][] , dp[t][]);
dp[now][] += dp[t][];
}
dp[t][] = dp[t][] = imp[t] = ;
}
if(!imp[now])
dp[now][] = min(dp[now][] , sum + );
newHead[now] = ;
}
bool cmp(int a , int b){
return dfn[a] < dfn[b];
}
int main(){
#ifndef ONLINE_JUDGE
freopen("613D.in" , "r" , stdin);
//freopen("613D.out" , "w" , stdout);
#endif
N = read();
; i < N ; ++i){
int a = read() , b = read();
addEd(Ed , head , cntEd , a , b);
addEd(Ed , head , cntEd , b , a);
}
init( , );
for(int M = read() ; M ; --M){
cnt = read();
; i <= cnt ; ++i)
num[i] = read();
sort(num + , num + cnt + , cmp);
create();
dfs();
][] , dp[][]);
printf( ? - : t);
}
;
}
CF613D Kingdom and its Cities 虚树的更多相关文章
- CF613D Kingdom and its Cities 虚树 树形dp 贪心
LINK:Kingdom and its Cities 发现是一个树上关键点问题 所以考虑虚树刚好也有标志\(\sum k\leq 100000\)即关键点总数的限制. 首先当k==1时 答案显然为0 ...
- 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
[CF613D]Kingdom and its Cities 题意:给你一棵树,每次询问给出k个关键点,问做多干掉多少个非关键点才能使得所有关键点两两不连通. $n,\sum k\le 10^5$ 题 ...
- CF613D:Kingdom and its Cities(树形DP,虚树)
Description 一个王国有n座城市,城市之间由n-1条道路相连,形成一个树结构,国王决定将一些城市设为重要城市. 这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领.而非重 ...
- CF613D Kingdom and its Cities(虚树+贪心)
很休闲的一个题啊 其实一看到关于\(\sum k\)的限制,就知道是个虚树的题了 首先我们把虚树建出来,然后考虑怎么计算个数呢? 我们令\(f[x]\)表示以\(x\)的子树中,剩余了多少个还没有切断 ...
- [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(虚树,动态规划)
[CF613D]Kingdom and its Cities(虚树,动态规划) 题面 洛谷 CF 翻译洛谷上有啦 题解 每次构建虚树,首先特判无解,也就是关键点中存在父子关系. 考虑\(dp\),设\ ...
- CodeForces - 613D:Kingdom and its Cities(虚树+DP)
Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in or ...
- Codeforces Round #613 Div.1 D.Kingdom and its Cities 贪心+虚树
题目链接:http://codeforces.com/contest/613/problem/D 题意概述: 给出一棵树,每次询问一些点,计算最少删除几个点可以让询问的点两两不连通,无解输出-1.保证 ...
随机推荐
- chrome 远程调试相关问题
1.使用chrome remote debug时打开inspect时出现一片空白 2.如何不用FQ可以享受Chrome for android的远程调试功能 3.chrome://appcache-i ...
- 纯小白入手 vue3.0 CLI - 3.1 - 路由 ( router )
vue3.0 CLI 真小白一步一步入手全教程系列:https://www.cnblogs.com/ndos/category/1295752.html 尽量把纷繁的知识,肢解重组成为可以堆砌的知识. ...
- JMeter http(s)测试脚本录制器的使用
JMeter http(s)测试脚本录制器的使用 by:授客 QQ:1033553122 http(s) Test Script Recorder允许Jmeter在你使用普通浏览器浏览web应用时,拦 ...
- 服务器 nginx配置 防止其他域名绑定自己的服务器
基于我的网站被其他的域名恶意绑定了,我做出了如下处理,全站转https,同时配置nginx跳转禁止其他绑定ip的域名访问(原理主机空域名可绑定任意的,参考https://www.jb51.net/ar ...
- java中传值方式的个人理解
前言 这几天在整理java基础知识方面的内容,对于值传递还不是特别理解,于是查阅了一些资料和网上相关博客,自己进行了归纳总结,最后将其整理成了一篇博客. 值传递 值传递是指在调用函数时将实际参数复制一 ...
- [20180730]exadata与行链接.txt
[20180730]exadata与行链接.txt --//最近一段时间在看<expert oracle exadata>,智能扫描的三大优化方法是:字段投影,谓词过滤,存储索引.大多数智 ...
- chrony时间服务器
chrony有着比ntp服务器更好的优势来同步服务,在集群架构中,采用此种服务来同步时间也是最好的方式. 在集群环境中,一般都是一个服务器,然后上百个客户端来同步服务端的时间,接下来我们看看如何配置. ...
- 使用sstream来进行类型转换
在某种情况下,我们不得不进行整型等数据类型与字符串类型的转换,比如,将“1234”转换为整数,常规的我们可以使用atoi函数来进行转换,或者是写一个循环来做转换,我们在这里也可以使用sstream类来 ...
- Alpha冲刺! Day12 - 砍柴
Alpha冲刺! Day12 - 砍柴 今日已完成 晨瑶:终于更了 Gitkraken 团队协作教程. 昭锡:初步学习了解Android动画. 永盛:用户逻辑基本完成. 立强:从众多开源库中找到两个合 ...
- JDBC学习笔记之JDBC简介
1. 引言 JDBC API是一种Java API,可以访问任何类型的表格数据,特别是存储在关系数据库中的数据. JDBC可以帮助我们编写下列三种编程活动的java应用程序: 1.连接到数据源,如数据 ...