【noip2018】【luogu5024】保卫王国
题目描述
Z 国有nn座城市,n - 1n−1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达。
Z 国的国防部长小 Z 要在城市中驻扎军队。驻扎军队需要满足如下几个条件:
- 一座城市可以驻扎一支军队,也可以不驻扎军队。
- 由道路直接连接的两座城市中至少要有一座城市驻扎军队。
- 在城市里驻扎军队会产生花费,在编号为i的城市中驻扎军队的花费是p_ipi。
小 Z 很快就规划出了一种驻扎军队的方案,使总花费最小。但是国王又给小 Z 提出 了mm个要求,每个要求规定了其中两座城市是否驻扎军队。小 Z 需要针对每个要求逐一 给出回答。具体而言,如果国王提出的第jj个要求能够满足上述驻扎条件(不需要考虑 第 jj 个要求之外的其它要求),则需要给出在此要求前提下驻扎军队的最小开销。如果 国王提出的第jj个要求无法满足,则需要输出-1 (1 ≤ j ≤ m)−1(1≤j≤m)。现在请你来帮助小 Z。
输入输出格式
输入格式:
第 11 行包含两个正整数n,mn,m和一个字符串typetype,分别表示城市数、要求数和数据类型。typetype是一个由大写字母 AA,BB 或 CC 和一个数字 11,22,33 组成的字符串。它可以帮助你获得部分分。你可能不需要用到这个参数。这个参数的含义在【数据规模与约定】中 有具体的描述。
第 22 行nn个整数p_ipi,表示编号ii的城市中驻扎军队的花费。
接下来 n - 1n−1 行,每行两个正整数u,vu,v,表示有一条uu到vv的双向道路。
接下来 mm 行,第jj行四个整数a,x,b,y(a ≠ b)a,x,b,y(a≠b),表示第jj个要求是在城市aa驻扎xx支军队, 在城市bb驻扎yy支军队。其中,xx 、 yy 的取值只有 00 或 11:若 xx 为 00,表示城市 aa 不得驻 扎军队,若 xx 为 11,表示城市 aa 必须驻扎军队;若 yy为 00,表示城市 bb不得驻扎军队, 若 yy为 11,表示城市 bb 必须驻扎军队。
输入文件中每一行相邻的两个数据之间均用一个空格分隔。
输出格式:
输出共 mm 行,每行包含 11 个整数,第jj行表示在满足国王第jj个要求时的最小开销, 如果无法满足国王的第jj个要求,则该行输出 -1−1。
输入输出样例
说明
【样例解释】
对于第一个要求,在 44 号和 55 号城市驻扎军队时开销最小。
对于第二个要求,在 11 号、22 号、33 号城市驻扎军队时开销最小。
第三个要求是无法满足的,因为在 11 号、55 号城市都不驻扎军队就意味着由道路直接连 接的两座城市中都没有驻扎军队。
【数据规模与约定】
对于 100\%100%的数据,n,m ≤ 100000,1 ≤ p_i ≤ 100000n,m≤100000,1≤pi≤100000。
数据类型的含义:
AA:城市ii与城市i + 1i+1直接相连。
BB:任意城市与城市 11 的距离不超过 100100(距离定义为最短路径上边的数量),即如果这 棵树以 11 号城市为根,深度不超过 100100。
CC:在树的形态上无特殊约束。
11:询问时保证a = 1,x = 1a=1,x=1,即要求在城市 11 驻军。对b,y没有限制。
22:询问时保证a,ba,b是相邻的(由一条道路直接连通)
33:在询问上无特殊约束。
题解:
首先一般的暴力$dp[u][0] = \sum dp[v][1]$ , $dp[u][1] = \sum min(dp[v][0],dp[v][1]) + a[u]$
复杂度$O(n^2)$
考虑倍增优化 :
fa[u][i]表示u向上跳2^i的祖先,然后用f[u][i]表示以fa[u][i]为根节点,不包括u的子树的最优dp值;
将f[u][i]写成一个2*2的矩阵,表示fa[u][i]和u是否选择;
更新一个点u,直接从u倍增到根节点就可以了;
考虑同时更新u和v,先跳到他们lca的儿子,再从lca跳到根,分类合并一下三个矩阵;
注意特判v和u有祖先关系的情况;
LCT做法:
其实这东西似乎叫动态dp
一般套路是将转移写成矩阵然后用数据结构维护;
树链剖分后 f[u][0/1]表示u为根的子树dp值,g[u][0/1]表示u为根的子树除开重儿子($son_{u}$)的dp值;
$f[u][0] = g[u][0] + f[son_{u}][1] $ ,
$f[u][1] = g[u][1] + min( f[son_{u}][0] , f[son_{u}][1] ) $
将加法定义成取min,乘法定义成加法,转移写成矩阵:$$\\
\begin{pmatrix} f[son_{u}][0] & f[son_{u}][1] \end{pmatrix} \
\begin{pmatrix} \infty & g[u][1] \\ g[u][0] & g[u][1] \end{pmatrix}
=
\begin{pmatrix} f[u][0] & f[u][1] \end{pmatrix}
$$
用LCT维护(只写了倍增,后面补上)
另外推荐一个动态dp的题:http://noi.ac/problem/111
#include<bits/stdc++.h>
#define il inline
#define rg register
#define ll long long
using namespace std;
const int N=;
ll inf=1e15;
struct mat{
ll c[][];
mat(ll _a=inf,ll _b=inf,ll _c=inf,ll _d=inf){
c[][]=_a;c[][]=_b;
c[][]=_c;c[][]=_d;
}
mat operator *(const mat&A){
mat ret;
for(int i=;i<;i++)
for(int j=;j<;j++){
ret.c[i][j]=min(inf,min(c[i][]+A.c[][j],c[i][]+A.c[][j]));
}
return ret;
}
}f[N][];
char gc(){
static char*p1,*p2,s[];
if(p1==p2)p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}
int rd(){
int x=; char c=gc();
while(c<''||c>'')c=gc();
while(c>=''&&c<='')x=(x<<)+(x<<)+c-'',c=gc();
return x;
}
int n,m,o,hd[N];
ll a[N],dep[N],fa[N][],bin[],dp[N][];
struct Edge{int v,nt;}E[N<<];
void adde(int u,int v){
E[o]=(Edge){v,hd[u]};hd[u]=o++;
E[o]=(Edge){u,hd[v]};hd[v]=o++;
}
void dfs0(int u,int F){
dp[u][]=;dp[u][]=a[u];
for(rg int i=hd[u];~i;i=E[i].nt){
int v=E[i].v;
if(v==F)continue;
dfs0(v,u);
dp[u][]+=dp[v][];
dp[u][]+=min(dp[v][],dp[v][]);
}
}
void dfs(int u,int F){
dep[u]=dep[fa[u][]=F]+;
f[u][]=mat(
inf,
dp[fa[u][]][]-dp[u][],
dp[fa[u][]][]-min(dp[u][],dp[u][]),
dp[fa[u][]][]-min(dp[u][],dp[u][])
);
for(rg int i=;bin[i]<dep[u];i++){
fa[u][i]=fa[fa[u][i-]][i-];
f[u][i]=f[fa[u][i-]][i-]*f[u][i-];
}
for(rg int i=hd[u];~i;i=E[i].nt){
int v=E[i].v;
if(v==F)continue;
dfs(v,u);
}
}
void solve(int u,int x,int v,int y){
if(dep[u]<dep[v])swap(u,v),swap(x,y);
mat tu,tv,t;
tu=mat(dp[u][],inf,inf,dp[u][]);
tv=mat(dp[v][],inf,inf,dp[v][]);
for(int i=;i<;i++)if(bin[i]&(dep[u]-dep[v])){
tu=f[u][i]*tu;
u=fa[u][i];
}
if(u==v){
ll ans;
t=mat(,inf,inf,);
for(int i=;i<;i++)if(bin[i]&(dep[u]-)){
t=f[u][i]*t;
u=fa[u][i];
}
ans= min(t.c[][y],t.c[][y])+tu.c[y][x];
if(ans>=inf)puts("-1");
else printf("%lld\n",ans);
return;
}
for(int i=;~i;i--)if(fa[u][i]!=fa[v][i]){
tu=f[u][i]*tu;
tv=f[v][i]*tv;
u=fa[u][i];
v=fa[v][i];
}
t=mat(
dp[fa[u][]][]-dp[u][]-dp[v][],
inf,
inf,
dp[fa[u][]][]-min(dp[u][],dp[u][])-min(dp[v][],dp[v][])
);
u=fa[u][];
for(int i=;i<;i++)if(bin[i]&(dep[u]-)){
t=f[u][i]*t;
u=fa[u][i];
}
ll ans=inf;
ans = min(
min(t.c[][],t.c[][])+tu.c[][x]+tv.c[][y],
min(t.c[][],t.c[][])+min(tu.c[][x],tu.c[][x])+min(tv.c[][y],tv.c[][y])
);
if(ans>=inf)puts("-1");
else printf("%lld\n",ans);
}
int main(){
freopen("defense.in","r",stdin);
freopen("defense.out","w",stdout);
n=rd(); m=rd(); gc(); gc();
for(rg int i=bin[]=;i<;i++)bin[i]=bin[i-]<<;
for(rg int i=;i<=n;i++)a[i]=rd(),hd[i]=-;
for(rg int i=;i<n;i++)adde(rd(),rd());
dfs0(,);
dfs(,);
for(rg int i=,u,v,x,y;i<=m;i++){
u=rd();x=rd();v=rd();y=rd();
solve(u,x,v,y);
}
return ;
}
倍增
【noip2018】【luogu5024】保卫王国的更多相关文章
- 「NOIP2018」保卫王国
「NOIP2018保卫王国」 题目描述 有一棵 \(n\) 个点, 点有点权 \(a_i\),\(m\) 组询问, 每次求钦点两个节点必须选或者必须不选后的树上最小点覆盖. \(1 \leq n, m ...
- noip2018 d2t3 保卫王国 解题报告
保卫王国 电脑卡懒得把题面挪过来了. 朴素 \[ dp_{i,0}=\sum dp_{s,1}\\ dp_{i,1}=\sum \min(dp_{s,0},dp_{s,1})+p_i \] 然后直接动 ...
- 【NOIP2018】保卫王国 动态dp
此题场上打了一个正确的$44pts$,接着看错题疯狂$rush$“正确”的$44pts$,后来没$rush$完没将之前的代码$copy$回去,直接变零分了..... 这一题我们显然有一种$O(nm)$ ...
- loj 2955 「NOIP2018」保卫王国 - 树链剖分 - 动态规划
题目传送门 传送门 想抄一个短一点ddp板子.然后照着Jode抄,莫名其妙多了90行和1.3k. Code /** * loj * Problem#2955 * Accepted * Time: 26 ...
- @NOIP2018 - D2T3@ 保卫王国
目录 @题目描述@ @题解@ @代码@ @题目描述@ Z 国有n座城市,n−1 条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻 ...
- NOIP2018 Day2T3 保卫王国
首先不考虑强制要求的话是一个经典问题,令 \(f_{i, 0 / 1}\) 为 \(i\) 选或不选时以 \(i\) 为根的子树的最优答案.那么就有转移 \(f_{u, 0} = \sum f_{v, ...
- 竞赛题解 - NOIP2018 保卫王国
\(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...
- LG5024 保卫王国
题意 题目描述 Z 国有\(n\)座城市,\(n - 1\)条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需要 ...
- Uoj 441 保卫王国
Uoj 441 保卫王国 动态 \(dp\) .今天才来写这个题. 设 \(f[u][0/1]\) 表示子树 \(u\) 中不选/选 \(u\) 时的最小权值和,显然有:\(f[u][0]=\sum ...
- [NOIP2018TG]保卫王国
[NOIP2018TG]保卫王国 BZOJ luogu 当动态dp模板题写的,(全集-最大点权独立集)不能放军队的+inf,必须放军队-inf即可 注意矩阵乘法的顺序问题 #define ll lon ...
随机推荐
- MySQL☞左外链接与右外连接
外链接查询:即要查询有关联关系的数据,还要查询没有关联关系的数据.(个人理解为:表A和表B两个关联的列中)如下图: emmm,简单的来说两个表的关联关系:book.bid=bookshop.id,他们 ...
- 这才是球王应有的技艺,他就是C罗
四年一度的世界杯在本周四拉开了帷幕,俄罗斯以5:0碾压沙特阿拉伯,让我们惊呼战斗名族的强大,其后的摩洛哥VS伊朗,摩洛哥前锋布哈杜兹将足球顶入自家球门,这......咳,咳,本来是为了解围,没想到成就 ...
- 如何计算FOB价格
FOB价格是国际贸易术语常有的一种算法,针对不同的对象,FOB价格也有不一样的算法.对于做外贸生意的朋友,需要了解FOB价格以及各项费用名称,以及如何计算FOB价格. FOB价格是国际FOB价格语常有 ...
- ES6的新特性(20)—— Module 的加载实现
Module 的加载实现 上一章介绍了模块的语法,本章介绍如何在浏览器和 Node 之中加载 ES6 模块,以及实际开发中经常遇到的一些问题(比如循环加载). 浏览器加载 传统方法 HTML 网页中, ...
- Intense Heat(前缀和或尺取)
The heat during the last few days has been really intense. Scientists from all over the Berland stud ...
- PSP Daily软件Alpha版本——基于NABCD评论,及改进建议
1.根据(不限于)NABCD评论作品的选题: 此软件的用户人群较为明确,即:用户(软件工程课上学生)记录例行报告.写每周PSP表格和统计的需求.潜在用户还有未来该课堂的学生和需要用PSP方法记录任务完 ...
- SpringMVC相关的面试题
1.什么是springMVC springmvc是spirng框架的一个模块,是一个基于MVC框架的web框架 2.springmvc的流程 a.客户端发送请求 b.前端控制器DispatcherSe ...
- Rsyslog-legacy(旧版本语法)配置说明及举例
1. RULES-书写规则 格式:日志设备(类型).日志级别 日志处理方式 (1)日志类型分类 auth pam产生的日志 authpriv ssh,ftp等登录信息的验证信息 ...
- Java多线程下单例
/* 多线程下的单例 */ //饿汉式 class Single { private static final Single s = new Single(); private Single(){} ...
- 使用kdump内核调试工具遇到的问题及解决
修改linux内核代码或者内核模块的时候,搞不好就会造成linux死机崩溃,crash死机后/var/log/kern.log里面不会有任何异常信息记录.这时候kdump就会派上用场了,网上kdump ...