Problem Here

Solution

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

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

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

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

动态dp~

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define max(a,b) ((a)>(b)?(a):(b))
  4. #define min(a,b) ((a)<(b)?(a):(b))
  5. inline ll read()
  6. {
  7. ll x=0,f=1;char ch=getchar();
  8. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  9. while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
  10. return x*f;
  11. }
  12. #define MN 100005
  13. #define inf 1000000005
  14. int n,m,v[MN];
  15. struct edge{int to,nex;}e[MN<<1];
  16. int hr[MN],en;
  17. std::set<int> mp[MN];
  18. inline void ins(int f,int t)
  19. {
  20. mp[f].insert(t);
  21. mp[t].insert(f);
  22. e[++en]=(edge){t,hr[f]};hr[f]=en;
  23. e[++en]=(edge){f,hr[t]};hr[t]=en;
  24. }
  25. int mx[MN],siz[MN],top[MN],fa[MN];
  26. void dfs1(int x,int f)
  27. {
  28. siz[x]=1;fa[x]=f;register int i;
  29. for(i=hr[x];i;i=e[i].nex)if(f^e[i].to)
  30. {
  31. dfs1(e[i].to,x);siz[x]+=siz[e[i].to];
  32. if(siz[e[i].to]>siz[mx[x]]) mx[x]=e[i].to;
  33. }
  34. }
  35. void dfs2(int x,int f,int tp)
  36. {
  37. top[x]=tp;if(mx[x]) dfs2(mx[x],x,tp);
  38. register int i;
  39. 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);
  40. }
  41. struct matrix
  42. {
  43. ll a[2][2];
  44. matrix(){memset(a,0,sizeof a);}
  45. matrix operator * (const matrix &b) const
  46. {
  47. register matrix c;register int i,j,k;
  48. for(i=0;i<2;++i)for(j=0;j<2;j++)for(k=0;k<2;++k)
  49. c.a[i][j]=max(c.a[i][j],b.a[i][k]+a[k][j]);
  50. return c;
  51. }
  52. }t[MN<<2],Ans;
  53. ll g[MN][2],f[MN][2],sum;
  54. int pos[MN],id[MN],dind,st[MN];
  55. void init(int x,int F)
  56. {
  57. register int i;g[x][1]=(ll)v[x];
  58. for(i=hr[x];i;i=e[i].nex)
  59. if((e[i].to^F)&&(e[i].to^mx[x]))
  60. {
  61. init(e[i].to,x);
  62. g[x][0]+=max(f[e[i].to][0],f[e[i].to][1]);
  63. g[x][1]+=f[e[i].to][0];
  64. }
  65. f[x][0]=g[x][0];f[x][1]=g[x][1];
  66. if(mx[x])
  67. {
  68. init(mx[x],x);
  69. f[x][0]+=max(f[mx[x]][0],f[mx[x]][1]);
  70. f[x][1]+=f[mx[x]][0];
  71. }
  72. pos[x]=++dind;id[dind]=x;
  73. if(st[top[x]]==0) st[top[x]]=dind;
  74. }
  75. #define mid ((l+r)>>1)
  76. void build(int k,int l,int r)
  77. {
  78. if(l==r)
  79. {
  80. t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0];
  81. t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll;
  82. return;
  83. }
  84. build(k<<1,l,mid);build(k<<1|1,mid+1,r);
  85. t[k]=t[k<<1]*t[k<<1|1];
  86. }
  87. void Modify(int k,int l,int r,int x)
  88. {
  89. if(l==r)
  90. {
  91. t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0];
  92. t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll;
  93. return;
  94. }
  95. if(x<=mid) Modify(k<<1,l,mid,x);
  96. else Modify(k<<1|1,mid+1,r,x);
  97. t[k]=t[k<<1]*t[k<<1|1];
  98. }
  99. matrix query(int k,int l,int r,int a,int b)
  100. {
  101. if(l==a&&r==b) return t[k];
  102. if(b<=mid) return query(k<<1,l,mid,a,b);
  103. if(a>mid) return query(k<<1|1,mid+1,r,a,b);
  104. return query(k<<1,l,mid,a,mid)*query(k<<1|1,mid+1,r,mid+1,b);
  105. }
  106. ll Que()
  107. {
  108. Ans=query(1,1,n,st[1],pos[1]);
  109. return max(Ans.a[0][0],Ans.a[1][0]);
  110. }
  111. inline void change(int x,ll add)
  112. {
  113. g[x][1]+=add;
  114. while(x!=0){
  115. Modify(1,1,n,pos[x]);
  116. matrix tmp=query(1,1,n,st[top[x]],pos[top[x]]);
  117. ll f0=tmp.a[0][0],f1=tmp.a[1][0];
  118. if(top[x]!=1){
  119. g[fa[top[x]]][1]+=f0-f[top[x]][0];
  120. g[fa[top[x]]][0]+=max(f1,f0)-max(f[top[x]][0],f[top[x]][1]);
  121. }
  122. f[top[x]][0]=f0;f[top[x]][1]=f1;
  123. x=fa[top[x]];
  124. }
  125. }
  126. int main()
  127. {
  128. register char ch[5];
  129. n=read(),m=read();scanf("%s",ch+1);
  130. register int i,j,a,b;
  131. for(i=1;i<=n;i++) v[i]=read(),sum+=1ll*v[i];
  132. for(i=1;i<n;i++) j=read(),ins(j,read());
  133. dfs1(1,0);dfs2(1,0,1);init(1,0);build(1,1,n);
  134. while(m--)
  135. {
  136. i=read();j=read();a=read(),b=read();
  137. if(j==0&&b==0&&mp[i].count(a))
  138. {
  139. puts("-1");
  140. continue;
  141. }
  142. change(i,(j==0?1:-1)*inf);
  143. change(a,(b==0?1:-1)*inf);
  144. printf("%lld\n",sum-Que()+1ll*(j==0?1:0)*inf+1ll*(b==0?1:0)*inf);
  145. change(i,(j==0?-1:1)*inf);
  146. change(a,(b==0?-1:1)*inf);
  147. }
  148. return 0;
  149. }

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. Java文件字符流

    1.字符编码(Character encoding)和编码集(Character set) 字符编码(Character encoding)是将字符转为字节或字节数组的过程. 字符集(Characte ...

  2. input里面的提示文字修改(placeholder里的文字修改,el-input也适用)

    input::-webkit-input-placeholder { /* WebKit browsers */ color: red; } input:-moz-placeholder { /* M ...

  3. c++ 使用torchscript 加载训练好的pytorch模型

    1.首先官网上下载libtorch,放到当前项目下 2.将pytorch训练好的模型使用torch.jit.trace导出为.pt格式 import torch from skimage import ...

  4. 配置CTS+

    Please let me know if below SAP KBA could help you: 1739340 - ESR/ID Export Using CTS+ option is dis ...

  5. Java8新特性概览

    Java8新特性简介 a)速度更快 1.对于JVM内存模型的新定义,将永久代从堆内存中移除,以前HotSpot JVM堆内存分为三块:1.年轻代  2.年老代  3.持久代  点击回顾 取而代之的是 ...

  6. Java之Math类使用小结

    Java的Math类封装了很多与数学有关的属性和方法,大致如下: public class Main { public static void main(String[] args) { // TOD ...

  7. 0001-代码仓库-git 命令

    参考 https://www.cnblogs.com/NTWang/p/6213408.html https://www.cnblogs.com/Sungeek/p/6905102.html

  8. log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment)的解决

    报错:log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironme ...

  9. 在openwrt上使用autossh(已放弃)

    用了一天后发现,这东西真不靠谱,还不如自已写的SHELL检测重连来的精准和方便,放弃中 参考文章: https://my.oschina.net/umu618/blog/849345 https:// ...

  10. CentOS7怎样安装MySQL5.7.22

    wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm下载mysql源安装包 yum install mysq ...