#2040 山贼集团

SDOI2008

题面
某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连。小村落用阿拉伯数字编号为1,2,3,4,…,n,山贼集团的总部设在编号为1的小村落中。山贼集团除了老大坐镇总部以外,其他的P个部门希望在村落的其他地方建立分部。P个分部可以在同一个小村落中建设,也可以分别建设在不同的小村落中。每个分部到总部的路径称为这个部门的管辖范围,于是这P个分部的管辖范围可能重叠,或者完全相同。在不同的村落建设不同的分部需要花费不同的费用。每个部门可能对他的管辖范围内的小村落收取保护费,但是不同的分部如果对同一小村落同时收取保护费,他们之间可能发生矛盾,从而损失一部分的利益,他们也可能相互合作,从而获取更多的利益。现在请你编写一个程序,确定P个分部的位置,使得山贼集团能够获得最大的收益。

输入
输入文件第一行包含一个整数N和P,表示绿荫村小村落的数量以及山贼集团的部门数量。
接下来N-1行每行包含两个整数X和Y,表示编号为X的村落与编号为Y的村落之间有一条道路相连。(1<=X,Y<=N)
接下来N行,每行P个正整数,第i行第j个数表示在第i个村落建设第j个部门的分部的花费Aij。
然后有一个正整数T,表示下面有T行关于山贼集团的分部门相互影响的代价。(0<=T<=2p)
最后有T行,每行最开始有一个数V,如果V为正,表示会获得额外的收益,如果V为负,则表示会损失一定的收益。然后有一个正整数C,表示本描述涉及的分部的数量,接下来有C个数,Xi,为分部门的编号(Xi不能相同)。表示如果C个分部Xi同时管辖某个小村落(可能同时存在其他分部也管辖这个小村落),可能获得的额外收益或者损失的收益为的|V|。T行中可能存在一些相同的Xi集合,表示同时存在几种收益或者损失。

输出
输出文件要求第一行包含一个数Ans,表示山贼集团设置所有分部后能够获得的最大收益。

样例输出
2 1
1 2
2 1
1
3 1 1

样例输入
5

数据规模
对于40%的数据,1<=P<=6。
对于100%的数据,1<=N<=100,1<=P<=12,保证答案的绝对值不超过10^8。

SOL
显然树形DP。
注意到DP时需要维护管辖当前节点的部门的状态,再看看数据规模,于是想到状压。
设f[i][j]f[i][j]f[i][j]表示村落iii被jjj这个状态所对应的部门管辖的时候的子树答案,可以考虑用背包转移:f[u][j]=maxf[u][jxork]+f[v][k]f[u][j]=max{f[u][j xor k]+f[v][k]}f[u][j]=maxf[u][jxork]+f[v][k]
另外,可以发现这道题所给的部门的收益信息,可以进行一波预处理——对于每一个组合,所有包含该组合的状态都可以预处理出一个收益,而f[i][j]f[i][j]f[i][j]需要被a[i][j]a[i][j]a[i][j]初始化。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
namespace Base{template<typename T>void chmax(T &x, T y){x=x<y?y:x;}}using namespace Base;
inline int rd(){int data=0,w=1;static char ch=0;ch=getchar();while(ch!='-'&&!isdigit(ch))ch=getchar();if(ch=='-')w=-1,ch=getchar();while(isdigit(ch))data=(data<<3)+(data<<1)+ch-'0',ch=getchar();return data*w;
}
inline void write(int x){if(x<0)x=-x,putchar('-');if(x>9)write(x/10);putchar(x%10+'0');}
const int N=105,S=4100,P=15;
int n,p,t,status,cnt,first[N],lo[S],a[N][P],val[S],f[N][S];
struct edge{int v,nxt;}e[N<<1];
inline void add(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
inline void dfs(int u,int fa){  for(int re i=first[u];i;i=e[i].nxt){int re v=e[i].v;if(v==fa)continue;dfs(v,u);for(int re j=status;j;j--)for(int re k=j;k;k=(k-1)&j)f[u][j]=max(f[u][j],f[u][j^k]+f[v][k]);}for(int re i=status;i;i--)f[u][i]+=val[i];
}
signed main(){n=rd(),p=rd(),status=(1<<p)-1;for(int re i=1;i<n;i++){int u=rd(),v=rd();add(u,v),add(v,u);}for(int re i=0;i<=p;i++)lo[1<<i]=i;for(int re i=1;i<=n;i++){for(int re j=0;j<p;j++)a[i][j]=rd();for(int re j=1;j<=status;j++)for(int k=j;k;k-=k&-k){int re s=k&-k;f[i][j]=f[i][j^s]-a[i][lo[s]];}}t=rd();for(int re i=1;i<=t;i++){int re v=rd(),c=rd(),st=0;while(c--){int re x=rd();st|=1<<(x-1);}val[st]+=v;int re arc_st=st^status;for(int re j=arc_st;j;j=(j-1)&arc_st)val[st|j]+=v;}dfs(1,0);write(f[1][status]);exit(0);
}

[FROM WOJ]#2040 山贼集团相关推荐

  1. 山贼集团 (group)

    山贼集团 (group) 题目描述 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连.小村落用阿拉伯数字编号为1,2,3,4,-,n ...

  2. P2465 [SDOI2008]山贼集团 dp

    这个题是一道树形dp+状压dp二合一,先预处理每种组合会有什么额外的费用,然后在树上dp就行了. 题干: 题目描述某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两个 ...

  3. 【SDOI2008】山贼集团

    本题的模型是树形状态压缩的动态规划. 首先考虑简单的题目模型:对于任何形态的有根树 T,都可以建立其等效二叉树 T',若在原树 T 中,结点 x 有儿子c1,c2,c3,-,ck c1,c2,c3,- ...

  4. 【Luogu】P2465山贼集团(树形状压DP)

    题目链接 写了个70分暴力还挂了,第一遍提交只拿了十分--海星 首先建虚拟节点多叉树转成二叉,然后子集枚举DP 设g[x][i]是以x为根的子树内山贼集合i,x啥都不选也没贡献的时候的最大价值 f[x ...

  5. 「SDOI 2008」山贼集团

    传送门 problem 给定一棵 nnn 个点且根为 111 的树,有 ppp 个部门,每个部门会占据一个点,占据点会有代价,不同部门可以占据同一个点,每个部门的管辖范围是 111 到他占据点的链上的 ...

  6. [SDOI2008]山贼集团【树上背包+状压】

    洛谷P2465 SOL 比较经典的一类树上背包问题套一个子集状压枚举. 注意到代价的计算与所选的点的集合有关,如果我们要统计代价需要状压记录点集,而数据范围非常配合的给了P≤12P\le12P≤12, ...

  7. 【学术篇】SDOI2008 山贼集团

    今天一月一号.. 突然想安利一波我的中二的2017总结- 传送门1:codevs 传送门2:luogu 时限5s和1s的区别(你没看我传送门都给的大牛分站了) 现在不仅线筛.. 有负数的快读都打不对了 ...

  8. 洛咕 P2465 [SDOI2008]山贼集团

    裸的状压dp. 设f[i][j]表示在i字数内放j集合的分部,直接sb转移. // luogu-judger-enable-o2 #include<bits/stdc++.h> #defi ...

  9. 【[SDOI2008]山贼集团】

    非常好的一道题 树上的状压\(dp\) 根据数据范围我们就能知道这是一道需要状压的题目 所以状态就是\(dp[i][S]\)表示在以\(i\)为根的子树里,选择的状态为\(S\)的最大收益 这个收益只 ...

最新文章

  1. Android开发学习之路--Notification之初体验
  2. LCD控制器与帧率、刷新率的关系分析
  3. 静态路由实验 +http+dns_华为静态路由配置实验
  4. 谈谈java并发锁(重入锁、读写锁、公平锁)
  5. oracle 如何查看oracle数据库版本
  6. 【若依(ruoyi)】表格图片预览功能图片超宽、超高问题
  7. java跳转_java servlet 几种页面跳转的方法
  8. leetcode83,删除有序链表中的重复元素
  9. React基础语法学习
  10. Java即时类| hashCode()方法与示例
  11. mysql数据库过滤空值_mysql必知必会--过 滤 数 据
  12. tensorflow之卷积神经网络
  13. 开源网络教学平台SAKAI开发环境的搭建
  14. C#软件工程师必备技能(工业自动化)
  15. android tv 下载地址,Android TV获取所有的应用apk
  16. Thinkpad T420 Fn热键在Windows10中的解决方案
  17. cad用键盘放大缩小_CAD放大缩小快捷键 _ 2D3D网
  18. fstream、ifstream、ofstream创建新文件
  19. ava.net.ConnectException: Connection refused: connect
  20. 老说技术更迭快,可十年到底可以淘汰多少知识?

热门文章

  1. 阿里新一轮组织调整:电商与本地生活进一步融合,淘系中坚力量崛起
  2. 知三维空间中任意旋转抛物面的顶点和焦点坐标,建立该旋转抛物面方程
  3. asp.net大学生二手物品交易网
  4. I2C调试遇到的问题以及解决办法---“busy死锁状态”以及“从设备地址无应答”问题
  5. VIDEOIO ERROR: V4L/V4L2: VIDIOC_S_CROP
  6. 痴情不是罪过 忘情不是洒脱
  7. XCode官方直接下载地址
  8. AI:人工智能领域算法思维导图集合之有监督学习/无监督学习/强化学习类型的具体算法简介(预测函数/优化目标/求解算法)、分类/回归/聚类/降维算法模型选择思路、11类机器学习算法详细分类之详细攻略
  9. VScode创建第一个C++项目
  10. 群邑智库:2018年1-9月主要央卫视电视剧回顾