状压dp

图上怎么跑dp?我们跑三进制状压dp,0表示选了,1表示既没选也没覆盖,2表示没选但是被覆盖了。

状态是dp[dep][S]表示当前走到了深度为dep的节点,状态为S,按照dfs序转移

每次转移就是计算这个点选了没选,然后像树形dp一样更新节点

返祖边也要处理

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 5e4 + ;
  4. int n, m, ans;
  5. vector<int> G[N];
  6. int dp[][N], c[N], vis[N], bin[], st[N], d[N];
  7. inline int rd()
  8. {
  9. int x = , f = ; char c = getchar();
  10. while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
  11. while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
  12. return x * f;
  13. }
  14. int bit(int S, int t)
  15. {
  16. return S / bin[t] % ;
  17. }
  18. void dfs(int u, int dep)
  19. {
  20. vis[u] = ;
  21. d[u] = dep;
  22. if(!dep)
  23. {
  24. dp[][] = c[u];
  25. dp[][] = ;
  26. dp[][] = 1e9;
  27. }
  28. else
  29. {
  30. int top = ;
  31. for(int i = ; i < G[u].size(); ++i)
  32. {
  33. int v = G[u][i];
  34. if(d[v] < d[u] && vis[v]) st[++top] = d[v];
  35. }
  36. for(int i = ; i < bin[dep + ]; ++i) dp[dep][i] = 1e9;
  37. for(int i = ; i < bin[dep]; ++i)
  38. {
  39. int U = , V = i;
  40. for(int j = ; j <= top; ++j) if(bit(i, st[j]) == ) U = ; else if(bit(i, st[j]) == ) V += bin[st[j]];
  41. dp[dep][i + U * bin[dep]] = min(dp[dep][i + U * bin[dep]], dp[dep - ][i]);
  42. dp[dep][V] = min(dp[dep][V], dp[dep - ][i] + c[u]);
  43. }
  44. }
  45. for(int i = ; i < G[u].size(); ++i)
  46. {
  47. int v = G[u][i];
  48. if(vis[v]) continue;
  49. dfs(v, dep + );
  50. for(int j = ; j < bin[dep + ]; ++j) dp[dep][j] = min(dp[dep + ][j], dp[dep + ][j + * bin[dep + ]]);
  51. }
  52. }
  53. int main()
  54. {
  55. n = rd();
  56. m = rd();
  57. bin[] = ;
  58. for(int i = ; i <= ; ++i) bin[i] = bin[i - ] * ;
  59. for(int i = ; i <= n; ++i) c[i] = rd();
  60. for(int i = ; i <= m; ++i)
  61. {
  62. int u = rd(), v = rd();
  63. G[u].push_back(v);
  64. G[v].push_back(u);
  65. }
  66. for(int i = ; i <= n; ++i) if(!vis[i])
  67. {
  68. dfs(i, );
  69. ans += min(dp[][], dp[][]);
  70. }
  71. printf("%d\n", ans);
  72. return ;
  73. }

bzoj3836的更多相关文章

  1. BZOJ3836 [Poi2014]Tourism 【树形dp +状压dp】

    题目链接 BZOJ3836 题解 显然这是个\(NP\)完全问题,此题的解决全仗任意两点间不存在节点数超过10的简单路径的性质 这意味着什么呢? \(dfs\)树深度不超过\(10\) \(10\)很 ...

  2. BZOJ3836 : [Poi2014]Tourism

    对于一个连通块,取一个点进行dfs,得到一棵dfs搜索树,则这棵树的深度不超过10,且所有额外边都是前向边. 对于每个点x,设S为三进制状态,S第i位表示根到x路径上深度为i的点的状态: 0:选了 1 ...

  3. OI动态规划&&优化 简单学习笔记

    持续更新!! DP的难点主要分为两类,一类以状态设计为难点,一类以转移的优化为难点. DP的类型 序列DP [例题]BZOJ2298 problem a 数位DP 常用来统计或者查找一个区间满足条件的 ...

  4. POI2014题解

    POI2014题解 [BZOJ3521][Poi2014]Salad Bar 把p当作\(1\),把j当作\(-1\),然后做一遍前缀和. 一个合法区间\([l,r]\)要满足条件就需要满足所有前缀和 ...

随机推荐

  1. centos 使用 CP 命令 不提示 覆盖

    今天 在我的VPS上拷一个目录,但放的地方有一个同名目录并且里面还有文件.如是直接拷过去,结果有N个要确认替换的提示,直接CTRL+C,在网上搜了把,发现有几个方法能够解决,方法例如以下: 一般我们使 ...

  2. sql quer

    SELECT (SELECT COUNT (sysid) FROM FwInvConsumable WHERE parentref = g.sysid AND (ns.state = 'Invento ...

  3. Django-Rest-Framework部分源码流程分析

    class TestView(APIView): ''' 调用这个函数的时候,会自动触发authentication_classes的运行,所以会先执行上边的类 ''' authentication_ ...

  4. 2018-11-13-常用模块1 (time random os sys)

    1.时间模块 time 2.随机数模块 random 3.与操作系统交互模块 os 4.系统模块 sys 在我们真正开始学习之前我们先解决下面几个问题,打好学习模块的小基础,以便更好的学习模块. (1 ...

  5. SAP bseg 使用注意点:1.不要使用;2.有主键再用,

    粗表-簇表 cluster-table BSEGRFBLG 池表 pool-table 我記的沒錯的話,在21天學會ABAP中有一節是專門在講Cluster table,另外在 www.sapfans ...

  6. qt使用中的一些问题(linux)

    ui_xxx.h的问题 工程中(工作空间)中包含的ui_xxx.h文件是系统自动生成的.这个是xxx.ui的创建文件来的,xxx.ui界面上的都是ui_xxx.h在控制的,在项目里是不显示这个头文件的 ...

  7. 如何缓存hbase数据以减少下次取数据的时间

    缓存从hbase取得的数据的好处是显而易见的,缓存到本地以后,如果下次的输入能够直接从已缓存的本地文件中取得数据就无需再次访问hbase数据库,这样一来数据量大的话可以节省大量的访问hbase数据库的 ...

  8. github for unity

  9. Pager-taglib

    <%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg" %> & ...

  10. Shell之历史操作记录与欢迎信息

    history: ~/.bash_history:用于记录所有的操作记录 欢迎信息:/etc/issue,只对本地登录生效. 远程终端的欢迎信息:/etc/issue.net