这是今天下午的互测题,只得了60多分

分析一下错因:

  $dis[i][j]$只记录了相邻的两个岛屿之间的距离,我一开始以为可以,后来$charge$提醒我有可能会出现来回走的情况,而状压转移就一次,无法实现来回走的情况,所以加了一个类似$floyed算法$的三重循环来更新每个点的距离,然后状态转移就可以了,枚举起点和终点,最后统计答案

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. char c[53][53];
  6. int n, m, dis[18][18], belong[53][53], f[40000][18], cnt = 0, qx[2500000], qy[2500000];
  7. int far[2500000], head, tail;
  8. bool vis[53][53];
  9. inline void _(int x, int y) {
  10. belong[x][y] = cnt;
  11. vis[x][y] = 1;
  12. if (x > 1 && c[x - 1][y] == 'X' && !vis[x - 1][y])
  13. _(x - 1, y);
  14. if (y > 1 && c[x][y - 1] == 'X' && !vis[x][y - 1])
  15. _(x, y - 1);
  16. if (x < n && c[x + 1][y] == 'X' && !vis[x + 1][y])
  17. _(x + 1, y);
  18. if (y < m && c[x][y + 1] == 'X' && !vis[x][y + 1])
  19. _(x, y + 1);
  20. }
  21. inline void __(int x) {
  22. int nowx, nowy;
  23. while (head != tail) {
  24. ++head; if ( head >= 2500000) head %= 2500000;
  25. nowx = qx[head];
  26. nowy = qy[head];
  27. if (nowx > 1 && !vis[nowx - 1][nowy] && c[nowx - 1][nowy] != '.') {
  28. if (c[nowx - 1][nowy] == 'S') {
  29. ++tail; if (tail >= 2500000) tail %= 2500000;
  30. qx[tail] = nowx - 1;
  31. qy[tail] = nowy;
  32. far[tail] = far[head] + 1;
  33. vis[nowx - 1][nowy] = 1;
  34. } else {
  35. dis[x][belong[nowx - 1][nowy]] = min( dis[x][belong[nowx - 1][nowy]], far[head]);
  36. }
  37. }
  38. if (nowy > 1 && !vis[nowx][nowy - 1] && c[nowx][nowy - 1] != '.') {
  39. if (c[nowx][nowy - 1] == 'S') {
  40. ++tail; if (tail >= 2500000) tail %= 2500000;
  41. qx[tail] = nowx;
  42. qy[tail] = nowy - 1;
  43. far[tail] = far[head] + 1;
  44. vis[nowx][nowy - 1] = 1;
  45. } else {
  46. dis[x][belong[nowx][nowy - 1]] = min( dis[x][belong[nowx][nowy - 1]], far[head]);
  47. }
  48. }
  49. if (nowx < n && !vis[nowx + 1][nowy] && c[nowx + 1][nowy] != '.') {
  50. if (c[nowx + 1][nowy] == 'S') {
  51. ++tail; if (tail >= 2500000) tail %= 2500000;
  52. qx[tail] = nowx + 1;
  53. qy[tail] = nowy;
  54. far[tail] = far[head] + 1;
  55. vis[nowx + 1][nowy] = 1;
  56. } else {
  57. dis[x][belong[nowx + 1][nowy]] = min( dis[x][belong[nowx + 1][nowy]], far[head]);
  58. }
  59. }
  60. if (nowy < m && !vis[nowx][nowy + 1] && c[nowx][nowy + 1] != '.') {
  61. if (c[nowx][nowy + 1] == 'S') {
  62. ++tail; if (tail >= 2500000) tail %= 2500000;
  63. qx[tail] = nowx;
  64. qy[tail] = nowy + 1;
  65. far[tail] = far[head] + 1;
  66. vis[nowx][nowy + 1] = 1;
  67. } else {
  68. dis[x][belong[nowx][nowy + 1]] = min( dis[x][belong[nowx][nowy + 1]], far[head]);
  69. }
  70. }
  71. }
  72. }
  73. int main() {
  74. scanf("%d%d\n", &n, &m);
  75. for(int i = 1; i <= n; ++i)
  76. for(int j = 1; j <= m; ++j) {
  77. c[i][j] = getchar();
  78. while (c[i][j] != 'X' && c[i][j] != '.' && c[i][j] != 'S')
  79. c[i][j] = getchar();
  80. }
  81. memset(vis, 0, sizeof(vis));
  82. for(int i = 1; i <= n; ++i)
  83. for(int j = 1; j <= m; ++j)
  84. if (!vis[i][j] && c[i][j] == 'X') {
  85. ++cnt;
  86. _(i, j);
  87. }
  88. memset(dis, 1, sizeof(dis));
  89. for(int i = 1; i <= cnt; ++i) {
  90. head = 0;
  91. tail = 0;
  92. memset(vis, 0, sizeof(vis));
  93. for(int k = 1; k <= n; ++k)
  94. for(int l = 1; l <= m; ++l)
  95. if (belong[k][l] == i) {
  96. vis[k][l] = 1;
  97. ++tail; if ( tail >= 2500000) tail %= 2500000;
  98. qx[tail] = k;
  99. qy[tail] = l;
  100. far[tail] = 0;
  101. }
  102. __(i);
  103. }
  104. for(int k = 1; k <= cnt; ++k)
  105. for(int i = 1; i <= cnt; ++i)
  106. for(int j = 1; j <= cnt; ++j)
  107. if (dis[i][k] + dis[k][j] < dis[i][j])
  108. dis[i][j] = dis[i][k] + dis[k][j];
  109. memset(f, 1, sizeof(f));
  110. int ans = 500000, tot = (1 << cnt) - 1;
  111. for(int i = 1; i <= cnt; ++i)
  112. f[1 << ( i - 1)][i] = 0;
  113. for(int i = 1; i <= tot; ++i) {
  114. for(int j = 1; 1 << (j - 1) <= i; ++j) {
  115. if (1 << (j - 1) & i) {
  116. for(int k = 1; k <= cnt; ++k)
  117. if (k != j && (1 << (k - 1) & i))
  118. f[i][j] = min(f[i][j], f[i ^ (1 << (j - 1))][k] + dis[k][j]);
  119. }
  120. }
  121. }
  122. for(int i = 1; i <= cnt; ++i)
  123. ans = min(ans, f[tot][i]);
  124. printf("%d\n",ans);
  125. return 0;
  126. }

以后思维得更严谨才行

我的BFS写的就是这么丑,这又怎样?

【BZOJ 3049】【USACO2013 Jan】Island Travels BFS+状压DP的更多相关文章

  1. BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS

    BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS Description Farmer John has taken the cows to a va ...

  2. hdu 4856 Tunnels (bfs + 状压dp)

    题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...

  3. HDU-4856 Tunnels (BFS+状压DP)

    Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In hi ...

  4. 孤岛营救问题(BFS+状压DP)

    孤岛营救问题 https://www.luogu.org/problemnew/show/P4011 用状压DP标记拿到钥匙的数量 #include<iostream> #include& ...

  5. QDUOJ 来自xjy的签到题(bfs+状压dp)

    来自xjy的签到题   Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1 ...

  6. HDU-3681-Prison Break(BFS+状压DP+二分)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  7. bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)

    Description  Input 本题包含多组数据. 第一行:一个整数T,表示数据的个数. 对于每组数据: 第一行:两个整数,N和K(含义如题目表述). 接下来N行:每行一个字符串. Output ...

  8. bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)

    Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...

  9. #12【BZOJ3003】LED BFS+状压DP

    题解: 看到区间修改先想一下差分 这题用差分是为了分析问题 现在的问题就变成了 原序列全为0,要使得特定的k个点变为1,每个操作改变x,y+1 然后我们会发现 对于二元组a,b我们要修改它,实际上是在 ...

随机推荐

  1. 《Writing Idiomatic Python》前两部分的中文翻译

    汇总了一下这本小书前两部分的内容: 翻译<Writing Idiomatic Python>(一):if语句.for循环 翻译<Writing Idiomatic Python> ...

  2. 最短路径问题的Dijkstra和SPFA算法总结

    Dijkstra算法: 解决带非负权重图的单元最短路径问题.时间复杂度为O(V*V+E) 算法精髓:维持一组节点集合S,从源节点到该集合中的点的最短路径已被找到,算法重复从剩余的节点集V-S中选择最短 ...

  3. u3d_Shader_effects笔记5 第二章 通过UV,进行纹理移动

    1.前面心情 公司最近打包,像我等小弟闲着,看代码容易困,没事偷着学shader,不过还是要多交流才行. 2.本文参考 这次参考比较多:由texture uv延伸问题多,主要是不明白变量定义: htt ...

  4. guava函数式编程

    [Google Guava] 4-函数式编程 原文链接 译文链接 译者:沈义扬,校对:丁一 注意事项 截至JDK7,Java中也只能通过笨拙冗长的匿名类来达到近似函数式编程的效果.预计JDK8中会有所 ...

  5. java 之前的安全的类回顾,以及以后需要线程安全时使用哪些类

    之前所学习到的线程安全的类: StringBuffer:线程安全的可变字符序列.一个类似于 String 的字符串缓冲区,但不能修改. Vector:Vector 类可以实现可增长的对象数组. Has ...

  6. Delphi项目构成之项目文件DPR

    1 2 3 4 5 6 7 8 9 10 11 12 13 program Project1;                         {关键字program,标准的Pascal源文件格式} ...

  7. Java 基础命名空间

    java.lang (提供利用 Java 编程语言进行程序设计的基础类)java.lang.annotation(提供了引用对象类,支持在某种程度上与垃圾回收器之间的交互)java.lang.inst ...

  8. 关于NOIP2016与NOI2018

    NOIP2016惨淡收场了,距离省一还有相当一大段距离,省队更是差了十条街去了,不过没关系. 既然已经对信息学产生了兴趣,竞赛无疑是最好的锻炼场所. 路是自己选择的,伤痕累累也要走下去. 还有一年,事 ...

  9. SQL Server数据库代码指令简介

    这些是比较常用的命令操作,事先声明,这些命令是不区分大小写的,我按照我的课本来总结用法和知识点,无用的章节自动省略. 没有一点数据库知识基础的可以等我录制视频,不然可能看不懂,视频链接:http:// ...

  10. WPF中的数据验证

    数据验证 WPF的Binding使得数据能够在数据源和目标之间流通,在数据流通的中间,便能够对数据做一些处理. 数据转换和数据验证便是在数据从源到目标 or 从目标到源 的时候对数据的验证和转换. V ...