Problem Here

Solution

这大概是一篇重复累赘的blog吧。

最小权覆盖集=全集-最大权独立集

强制取或不取,可以通过将权值修改成inf或者-inf

然后就用动态dp的套路就行了

动态dp~

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define MN 100005
#define inf 1000000005
int n,m,v[MN];
struct edge{int to,nex;}e[MN<<1];
int hr[MN],en;
std::set<int> mp[MN];
inline void ins(int f,int t)
{
mp[f].insert(t);
mp[t].insert(f);
e[++en]=(edge){t,hr[f]};hr[f]=en;
e[++en]=(edge){f,hr[t]};hr[t]=en;
}
int mx[MN],siz[MN],top[MN],fa[MN];
void dfs1(int x,int f)
{
siz[x]=1;fa[x]=f;register int i;
for(i=hr[x];i;i=e[i].nex)if(f^e[i].to)
{
dfs1(e[i].to,x);siz[x]+=siz[e[i].to];
if(siz[e[i].to]>siz[mx[x]]) mx[x]=e[i].to;
}
}
void dfs2(int x,int f,int tp)
{
top[x]=tp;if(mx[x]) dfs2(mx[x],x,tp);
register int i;
for(i=hr[x];i;i=e[i].nex)if((e[i].to^f)&&(e[i].to^mx[x])) dfs2(e[i].to,x,e[i].to);
}
struct matrix
{
ll a[2][2];
matrix(){memset(a,0,sizeof a);}
matrix operator * (const matrix &b) const
{
register matrix c;register int i,j,k;
for(i=0;i<2;++i)for(j=0;j<2;j++)for(k=0;k<2;++k)
c.a[i][j]=max(c.a[i][j],b.a[i][k]+a[k][j]);
return c;
}
}t[MN<<2],Ans;
ll g[MN][2],f[MN][2],sum;
int pos[MN],id[MN],dind,st[MN];
void init(int x,int F)
{
register int i;g[x][1]=(ll)v[x];
for(i=hr[x];i;i=e[i].nex)
if((e[i].to^F)&&(e[i].to^mx[x]))
{
init(e[i].to,x);
g[x][0]+=max(f[e[i].to][0],f[e[i].to][1]);
g[x][1]+=f[e[i].to][0];
}
f[x][0]=g[x][0];f[x][1]=g[x][1];
if(mx[x])
{
init(mx[x],x);
f[x][0]+=max(f[mx[x]][0],f[mx[x]][1]);
f[x][1]+=f[mx[x]][0];
}
pos[x]=++dind;id[dind]=x;
if(st[top[x]]==0) st[top[x]]=dind;
}
#define mid ((l+r)>>1)
void build(int k,int l,int r)
{
if(l==r)
{
t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0];
t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll;
return;
}
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
t[k]=t[k<<1]*t[k<<1|1];
}
void Modify(int k,int l,int r,int x)
{
if(l==r)
{
t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0];
t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll;
return;
}
if(x<=mid) Modify(k<<1,l,mid,x);
else Modify(k<<1|1,mid+1,r,x);
t[k]=t[k<<1]*t[k<<1|1];
}
matrix query(int k,int l,int r,int a,int b)
{
if(l==a&&r==b) return t[k];
if(b<=mid) return query(k<<1,l,mid,a,b);
if(a>mid) return query(k<<1|1,mid+1,r,a,b);
return query(k<<1,l,mid,a,mid)*query(k<<1|1,mid+1,r,mid+1,b);
}
ll Que()
{
Ans=query(1,1,n,st[1],pos[1]);
return max(Ans.a[0][0],Ans.a[1][0]);
}
inline void change(int x,ll add)
{
g[x][1]+=add;
while(x!=0){
Modify(1,1,n,pos[x]);
matrix tmp=query(1,1,n,st[top[x]],pos[top[x]]);
ll f0=tmp.a[0][0],f1=tmp.a[1][0];
if(top[x]!=1){
g[fa[top[x]]][1]+=f0-f[top[x]][0];
g[fa[top[x]]][0]+=max(f1,f0)-max(f[top[x]][0],f[top[x]][1]);
}
f[top[x]][0]=f0;f[top[x]][1]=f1;
x=fa[top[x]];
}
}
int main()
{
register char ch[5];
n=read(),m=read();scanf("%s",ch+1);
register int i,j,a,b;
for(i=1;i<=n;i++) v[i]=read(),sum+=1ll*v[i];
for(i=1;i<n;i++) j=read(),ins(j,read());
dfs1(1,0);dfs2(1,0,1);init(1,0);build(1,1,n);
while(m--)
{
i=read();j=read();a=read(),b=read();
if(j==0&&b==0&&mp[i].count(a))
{
puts("-1");
continue;
}
change(i,(j==0?1:-1)*inf);
change(a,(b==0?1:-1)*inf);
printf("%lld\n",sum-Que()+1ll*(j==0?1:0)*inf+1ll*(b==0?1:0)*inf);
change(i,(j==0?-1:1)*inf);
change(a,(b==0?-1:1)*inf);
}
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

[luogu 5024] 保卫王国的更多相关文章

  1. [倍增][换根DP]luogu P5024 保卫王国

    题面 https://www.luogu.com.cn/problem/P5024 分析 可以对有限制的点对之间的链进行在倍增上的DP数组合并. 需要通过一次正向树形DP和一次换根DP得到g[0][i ...

  2. 洛谷5024 保卫王国 (动态dp)

    qwq非正解. 但是能跑过. 1e5 log方还是很稳的啊 首先,考虑最普通的\(dp\) 令\(dp1[x][0]表示不选这个点,dp1[x][1]表示选这个点的最大最小花费\) 那么 \(dp1[ ...

  3. [NOIP2018TG]保卫王国

    [NOIP2018TG]保卫王国 BZOJ luogu 当动态dp模板题写的,(全集-最大点权独立集)不能放军队的+inf,必须放军队-inf即可 注意矩阵乘法的顺序问题 #define ll lon ...

  4. noip2018 d2t3 保卫王国 解题报告

    保卫王国 电脑卡懒得把题面挪过来了. 朴素 \[ dp_{i,0}=\sum dp_{s,1}\\ dp_{i,1}=\sum \min(dp_{s,0},dp_{s,1})+p_i \] 然后直接动 ...

  5. LG5024 保卫王国

    题意 题目描述 Z 国有\(n\)座城市,\(n - 1\)条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需要 ...

  6. 「NOIP2018」保卫王国

    「NOIP2018保卫王国」 题目描述 有一棵 \(n\) 个点, 点有点权 \(a_i\),\(m\) 组询问, 每次求钦点两个节点必须选或者必须不选后的树上最小点覆盖. \(1 \leq n, m ...

  7. Uoj 441 保卫王国

    Uoj 441 保卫王国 动态 \(dp\) .今天才来写这个题. 设 \(f[u][0/1]\) 表示子树 \(u\) 中不选/选 \(u\) 时的最小权值和,显然有:\(f[u][0]=\sum ...

  8. 竞赛题解 - NOIP2018 保卫王国

    \(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...

  9. 『保卫王国 树上倍增dp』

    保卫王国 Description Z 国有n座城市,n - 1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需 ...

随机推荐

  1. 传统IDC 部署网站

    选择IDC机房 1.选择云主机. 2.传统IDC a购买服务器 b服务器托管 c装系统 装系统 虚拟机软件 vmware workstation virtualbox hyper-v 下载:r.ami ...

  2. 聊聊 ES6 中的箭头函数

    首先来两点: 当只有一个参数的时候,那么 () 可以省略 当只有一个 return 的时候,那么 {} 可以省略 当函数体内只有一条语句的时候,那么 {} 也可以省略 下面来几个简单的例子来对比 ES ...

  3. Step by Step to create orders by consuming SAP Commerce Cloud Restful API

    Recently Jerry is working on an integration project about creating orders in Wechat platform by cons ...

  4. org.apache.shiro.session.UnknownSessionException: There is no session with id [xxxx]的解决方案

    org.apache.shiro.session.UnknownSessionException: There is no session with id [xxxx]的解决方案 背景描述 Sprin ...

  5. java23种设计模式专攻:生产者-消费者模式的三种实现方式

    公司的架构用到了dubbo.带我那小哥也是个半吊子,顺便就考我生产者消费者模式,顺便还考我23种java设计模式,

  6. Python学习日记(二) list操作

    l = ['a','b','c','d',1,2,[3,'e',4]] 1.list.append() 在list的结尾新增一个新的元素,没有返回值,但会修改原列表 l.append(5) print ...

  7. git 如何忽略已经加入到版本控制的文件

    增加 .gitignore 文件,里面添加需要忽略的文件(file_not_wanted): 执行命令 git rm -r --cached .   注意,最后的点.不要省略. 最后重新将所有文件添加 ...

  8. LINQ查询表达式(1) - 查询表达式基础

    LINQ包括五个部分:LINQto Objects.LINQ to DataSets.LINQ to SQL.LINQ to Entities.LINQ to XML. 什么是查询?它有什么用途? “ ...

  9. 关于devexpress报表XtraReport,动态修改报表样式(.repx格式),动态添加数据并使用的理解

    一.基本概念: XtraReports 中的每个报表都由 XtraRepot 类的一个实例表示,或者由该类的子类来表示(这种情况更常见). 因此,每个报表都作为带区的容器使用,而每个带区中都包含报表控 ...

  10. BAT文件的调用

    分成2个步骤,首先生成一个bat文件,然后调用批处理文件 1.生成.bat文件 入参为文件的内容,filePath为绝对路径,且需要扩展名(这个方法不局限于生成.bat文件,也可以生成其他扩展名文件) ...