LINK:T3



比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到。

一看到题求删除点的最少个 可以使得不连通。

瞬间想到最小割 发现对于10分直接跑最小割即可。

不过想要通过n^2需要一些奇技 如从Si跑到Tj 想要得到i到j+1的答案 只需要再从Tj跑到Tj+1即可。

可以发现这样做是有正确性的保证的 这样最多跑n次整张图的最大流。

且增广路不断减小 速度比较快。

  1. const int MAXN = 40010;
  2. int n, k, id, cc, len;
  3. ll ans;
  4. char a[MAXN][10][10];
  5. int w[MAXN][10][2], S[MAXN], T[MAXN];
  6. int lin[MAXN * 10], ver[MAXN * 100], nex[MAXN * 100], e[MAXN * 100], e1[MAXN * 100];
  7. int vis[MAXN * 10], d[MAXN * 10], q[MAXN * 10];
  8. inline void add(int x, int y, int z) {
  9. ver[++len] = y;
  10. nex[len] = lin[x];
  11. lin[x] = len;
  12. e[len] = z;
  13. e1[len] = z;
  14. ver[++len] = x;
  15. nex[len] = lin[y];
  16. lin[y] = len;
  17. e[len] = 0;
  18. e1[len] = 0;
  19. }
  20. inline int bfs(int S, int T) {
  21. ++cc;
  22. int h = 0, t = 0;
  23. q[++t] = S;
  24. d[S] = 1;
  25. vis[S] = cc;
  26. while (h++ < t) {
  27. int x = q[h];
  28. for (int i = lin[x]; i; i = nex[i]) {
  29. int tn = ver[i];
  30. if (vis[tn] == cc || !e[i])
  31. continue;
  32. vis[tn] = cc;
  33. q[++t] = tn;
  34. d[tn] = d[x] + 1;
  35. if (tn == T)
  36. return 1;
  37. }
  38. }
  39. return 0;
  40. }
  41. inline int dinic(int x, int flow, int T) {
  42. if (x == T)
  43. return flow;
  44. int rest = flow, k;
  45. for (int i = lin[x]; i && rest; i = nex[i]) {
  46. int tn = ver[i];
  47. if (e[i] && d[tn] == d[x] + 1) {
  48. k = dinic(tn, min(rest, e[i]), T);
  49. if (!k)
  50. d[tn] = 0;
  51. e[i] -= k;
  52. e[i ^ 1] += k;
  53. rest -= k;
  54. }
  55. }
  56. return flow - rest;
  57. }
  58. inline void bf() {
  59. ans = 0;
  60. rep(1, n, i) rep(i + 1, n, j) {
  61. rep(2, len, w) e[w] = e1[w];
  62. int flow = 0;
  63. while (bfs(S[i], T[j]))
  64. while ((flow = dinic(S[i], INF, T[j]))) ans += flow;
  65. }
  66. putl(ans);
  67. }
  68. inline void sol() {
  69. ans = 0;
  70. rep(1, n, i) {
  71. rep(2, len, w) e[w] = e1[w];
  72. rep(i + 1, n, j) {
  73. int flow = 0, cnt = 0;
  74. while (bfs(j - 1 == i ? S[i] : T[j - 1], T[j]))
  75. while ((flow = dinic((j - 1 == i) ? S[i] : T[j - 1], INF, T[j]))) cnt += flow;
  76. ans += cnt;
  77. }
  78. }
  79. putl(ans);
  80. }
  81. int main() {
  82. freopen("T3.in", "r", stdin);
  83. freopen("T3.out", "w", stdout);
  84. gt(n);
  85. gt(k);
  86. rep(1, n, i) {
  87. rep(1, k, j) {
  88. if (i != n) {
  89. gc(a[i][j]);
  90. // rep(1,k,cc)cout<<a[i][j][cc];
  91. // cout<<endl;
  92. }
  93. w[i][j][0] = ++id;
  94. w[i][j][1] = ++id;
  95. }
  96. S[i] = ++id;
  97. T[i] = ++id;
  98. }
  99. len = 1;
  100. rep(1, n, i) {
  101. rep(1, k, r) {
  102. add(w[i][r][1], T[i], INF);
  103. add(S[i], w[i][r][0], INF);
  104. add(w[i][r][0], w[i][r][1], 1);
  105. if (i != n)
  106. rep(1, k, cc) if (a[i][r][cc] == '1') add(w[i][r][1], w[i + 1][cc][0], INF);
  107. }
  108. }
  109. if (n <= 100)
  110. bf();
  111. else
  112. sol();
  113. return 0;
  114. }

剩下的时间又又又去刚T2了就没细想。

正解:容易发现答案<=k 也同时存在 f(i,j)>=f(i,j+1)

由于点数较少 容易想到一个状压 设f[i][j][k]表示当前到了第i层此时删掉了j个点当前能到的集合为k.

一旦到达某一层集合为空 就说明删掉的这些点就可以阻断。

需要求出来 答案 利用这个状态进行差分就能快速求出到某一层的答案。

值得一提的是由于起点不固定终点基本上固定 所以倒着跑到每一个起点这样之前的dp数组还是可以使用的。

考虑转移 先承接上一层的转移 再考虑对当前集合删掉一些点。

枚举这个决策的时候直观的可以直接枚举子集 不过这样复杂度\(3^k\).

优化就是 可以利用之前的状态 只需要枚举删掉哪个点就可以得到之前的状态。

细节挺多。

  1. const int MAXN=40010;
  2. int n,k,maxx;ll ans;
  3. int f[2][10][1<<9];
  4. char a[MAXN][10][10];
  5. int go[MAXN][1<<9];
  6. int w[MAXN],p[1<<9];
  7. int main()
  8. {
  9. freopen("T3.in","r",stdin);
  10. freopen("T3.out","w",stdout);
  11. //freopen("1.in","r",stdin);
  12. gt(n);gt(k);
  13. maxx=(1<<k)-1;
  14. rep(1,k,i)p[1<<(i-1)]=i;
  15. rep(1,n-1,i)
  16. {
  17. rep(1,k,j)
  18. {
  19. gc(a[i][j]);w[j]=0;
  20. rep(1,k,c)if(a[i][j][c]=='1')w[j]=w[j]|(1<<(c-1));
  21. }
  22. rep(0,maxx,j)go[i][j]=go[i][j-(j&(-j))]|w[p[j&(-j)]];
  23. }
  24. //f[i][j][k]表示到达第i层删掉的点数为j此时当前这层状态为k所能到达的最早的层数.
  25. memset(f,0x3f,sizeof(f));
  26. int u=0;
  27. fep(n,1,i)
  28. {
  29. u=u^1;
  30. rep(0,k,j)rep(0,maxx,c)f[u][j][c]=f[u^1][j][go[i][c]];
  31. f[u][0][0]=i;
  32. rep(1,k,j)rep(0,maxx,c)
  33. {
  34. for(int cc=c;cc;cc=cc-(cc&(-cc)))
  35. f[u][j][c]=min(f[u][j][c],f[u][j-1][c-(cc&(-cc))]);
  36. }
  37. rep(1,k,j)
  38. {
  39. if(f[u][j][maxx]>=INF)continue;
  40. ans+=((f[u][j-1][maxx]>=INF?n+1:f[u][j-1][maxx])-(j==k?i+1:f[u][j][maxx]))*j;
  41. }
  42. }
  43. putl(ans);
  44. return 0;
  45. }

4.26 省选模拟赛 T3 状压dp 差分求答案的更多相关文章

  1. NOIp模拟赛 巨神兵(状压DP 容斥)

    \(Description\) 给定\(n\)个点\(m\)条边的有向图,求有多少个边集的子集,构成的图没有环. \(n\leq17\). \(Solution\) 问题也等价于,用不同的边集构造DA ...

  2. BZOJ_2734_[HNOI2012]集合选数_构造+状压DP

    BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...

  3. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  4. 2018.10.17 NOIP模拟 管道(状压dp)

    传送门 状压dp好题. 怎么今天道道题都有点东西啊 对于今天题目神仙出题人先膜为上策:%%%%DzYoAk_UoI%%%% 设f[i][j]f[i][j]f[i][j]表示选取点的状态集合为iii,当 ...

  5. 模拟赛毒瘤状压DP题:Kronican

    Kronican 内存限制:32 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: cqbzgm 题目描述 Mislav有N个无限体积的杯子,每一个杯子中都 ...

  6. 2018.09.08 NOIP模拟 division(状压dp)

    这么sb的题考场居然写挂了2233. 假设n=∏iaiki" role="presentation" style="position: relative;&qu ...

  7. 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)

    [描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...

  8. Codeforces 79D - Password(状压 dp+差分转化)

    Codeforces 题目传送门 & 洛谷题目传送门 一个远古场的 *2800,在现在看来大概 *2600 左右罢( 不过我写这篇题解的原因大概是因为这题教会了我一个套路罢( 首先注意到每次翻 ...

  9. 7.12 NOI模拟赛 生成树 装压dp vector装压

    LINK:生成树 这场比赛我打的真失败 T3是比较容易的 却一直刚 那道"数论" 10分其实搜一下全排列. 30分容易想到对边进行装压dp. 不过存在一些细节 可以对于一个连通块的 ...

随机推荐

  1. 状压DP之Bill的挑战

    题目 P2167 [SDOI2009]Bill的挑战 Sheng bill不仅有惊人的心算能力,还可以轻松地完成各种统计.在昨天的比赛中,你凭借优秀的程序与他打成了平局,这导致Sheng bill极度 ...

  2. plus.runtime.quit()是个好函数

    对于H5+APP开发,应用的生命周期监听函数里是对应用行为的监控,但是并不对应用执行退出或重启操作.相关操作还是要使用mui

  3. 1. 初识Jackson -- 世界上最好的JSON库

    要想人前显贵,必须背后受罪.关注公众号[BAT的乌托邦]开启专栏式学习,拒绝浅尝辄止.本文 https://www.yourbatman.cn 已收录,里面一并有Spring技术栈.MyBatis.中 ...

  4. python中可变类型和不可变类型

    1.python中的可变类型和不可变类型 python中的数据类型大致可分为6类:1.Number(数字) 2. String(字符串) 3. Tuple (元组) 4. List(列表) 5. Di ...

  5. JVM 专题十一:运行时数据区(六)方法区

    1. 栈.堆.方法区关系交互 运行时数据区结构图: 从线程共享与否的角度来看: 2. 方法区的理解 2.1 方法区在哪里? <Java虚拟机规范>中明确说明:“尽管所有的方法区在逻辑上属于 ...

  6. Flask 基础组件(八):message

    message是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除. from flask import Flask, flash, redirect, render_templ ...

  7. Mysql and ORM

    本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql ORM sql ...

  8. Zabbix 4.0 API 实践,主机/主机群组 批量添加模板和删除模板

    场景 我们日常在管理Zabbix 的时候,经常会需要批量添加模板和批量删除模板,Zabbix页面是提供的批量链接的功能,但是它链接的也只是当前页的主机,我们想扩展这个功能,在链接的时候,可以批量链接整 ...

  9. .NET Core微服务开发服务间调用篇-GRPC

    在单体应用中,相互调用都是在一个进程内部调用,也就是说调用发生在本机内部,因此也被叫做本地方法调用:在微服务中,服务之间调用就变得比较复杂,需要跨网络调用,他们之间的调用相对于与本地方法调用,可称为远 ...

  10. (数据科学学习手札90)Python+Kepler.gl轻松制作时间轮播图

    本文示例代码及数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 Kepler.gl作为一款强大的开源地理信 ...