题意:一个R行C列的矩阵,'X'表示地,'S'表示浅水,'.'表示不能走的深水。连通的X视为一个岛(不超过15个)。现在要走完所有岛,求最少的踩在浅水格子的次数。

题解:岛屿不超过15个,明显的暗示可以用状态压缩DP跑旅行商问题。但是这题需要较多的预处理。首先给每个X连通块标上岛屿的序号,然后对每一个岛屿,将它直接相邻的浅水格子压入队列跑BFS即可求出所有岛屿到他的距离。然后记得一定要跑一次Floyd!!DP的状态定义为f[s, i]表示经过了的岛屿的集合为s,最后到达i的最少路径长。

考试的时候犯了很SB的两个错误,说明写代码的时候思路不清晰。以后最好写一个函数就检查一个。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define Min(a,b) ((a)<(b)?(a):(b))
#define inmap(x,y) (x>0 && y>0 && x<=R && y<=C)
const int MAXN = 105;
const int dd[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int N, R, C;
int dis[20][20];
char sea[MAXN][MAXN];
int cnt;
const int INF = 0x3f3f3f3f;#define code(x,y) ((x-1)*C+y)
#define getx(s) ((s-1)/C+1)
#define gety(s) ((s-1)%C+1)
void mark(int x, int y)
{queue<int> Q;Q.push(code(x,y));++cnt;while (!Q.empty()) {x = getx(Q.front());y = gety(Q.front());sea[x][y] = cnt;Q.pop();for (int i = 0; i<4; ++i) {int tx = x+dd[i][0], ty = y+dd[i][1];if (inmap(tx,ty) && sea[tx][ty]=='X')Q.push(code(tx, ty));}}
}int step[MAXN][MAXN];
void BFS(int id)
{int i, j, k, x, y, tx, ty;queue<int> Q;memset(step, 0, sizeof step);for (i = 1; i<=R; ++i)for (j = 1; j<=C; ++j)if (sea[i][j] == id)for (k = 0; k<4; ++k) {tx = i+dd[k][0], ty = j+dd[k][1];if (inmap(tx,ty) && sea[tx][ty]=='S')//考试的时候居然忘记判断是否是浅水就直接入队了!!Q.push(code(tx, ty)), step[tx][ty] = 1;}while (!Q.empty()) {x = getx(Q.front()), y = gety(Q.front());Q.pop();for (i = 0; i<4; ++i) {tx = x+dd[i][0], ty = y+dd[i][1];if (!inmap(tx,ty)) continue;if (sea[tx][ty]=='S' && !step[tx][ty])Q.push(code(tx,ty)), step[tx][ty] = step[x][y]+1;else if (1<=sea[tx][ty] && sea[tx][ty]<=cnt && sea[tx][ty]!=id) {j = sea[tx][ty];dis[id][j] = Min(dis[id][j], step[x][y]),dis[j][id] = dis[id][j];}}}
}void Floyd()//考试的时候忘记加floyd了,以后一定要注意这些细节。
{for (int k = 1; k<=cnt; ++k)for (int i = 1; i<=cnt; ++i)for (int j = 1; j<=cnt; ++j)dis[i][j] = Min(dis[i][j], dis[i][k] + dis[k][j]);
}int f[(1<<16)+1][16];
int ans = INF;
void DoDP()
{ memset(f, 0x3f, sizeof f);int s, s1, i, j;for (i = 1; i<=cnt; ++i)f[1<<(i-1)][i] = 0;for (s = 1; s < (1<<cnt); ++s)for (i = 1; i<=cnt; ++i){if (!(s&(1<<(i-1)))) continue;s1 = s ^ (1<<(i-1));for (j = 1; j<=cnt; ++j){if (!(s1&(1<<(j-1)))) continue;f[s][i] = Min(f[s][i], f[s1][j]+dis[j][i]);}}for (i = 1; i<=cnt; ++i)ans = Min(ans, f[(1<<cnt)-1][i]);
}int main()
{ int i, j; scanf("%d%d", &R, &C); memset(dis, 0x3f, sizeof dis); for (i = 1; i<=R; ++i) scanf("%s", sea[i]+1); for (i = 1; i<=R; ++i) for (j = 1; j<=C; ++j) if (sea[i][j] == 'X') mark(i, j); for (i = 1; i<=cnt; ++i) BFS(i); Floyd();DoDP();printf("%d\n", ans);return 0;
}

USACO2013 island travels相关推荐

  1. 【BZOJ3049】Island Travels,SPFA预处理+状态压缩DP

    传送门(权限题) 3049: [Usaco2013 Jan]Island Travels Time Limit: 10 Sec Memory Limit: 128 MB Submit: 84 Solv ...

  2. #USACO#Island Travels

    [USACO 2013 1月金组]Island Travels 时间限制: 1 Sec  内存限制: 128 MB 题目描述 FJ组织它的奶牛去海边度假.海边有N(N<=15)个岛屿,这些岛屿分 ...

  3. [Leetcode] Max Area of Island 最大岛屿面积

    Max Area of Island 最新更新请见:https://yanjia.me/zh/2019/02/... Given a non-empty 2D array grid of 0's an ...

  4. bzoj1791: [Ioi2008]Island 岛屿 单调队列优化dp

    1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1826  Solved: 405 [Submit] ...

  5. hdu4280 Island Transport 网络流最大流 Dinic算法高效模板

    Island Transport In the vast waters far far away, there are many islands. People are living on the i ...

  6. HDU Problem - 4280 Island Transport(最大流)

    题目链接 Problem Description In the vast waters far far away, there are many islands. People are living ...

  7. LeetCode 695 Max Area of Island

    题目: Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) ...

  8. [Swift]LeetCode463. 岛屿的周长 | Island Perimeter

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  9. Treasure Island CodeForces - 1214D(dfs)

    All of us love treasures, right? That's why young Vasya is heading for a Treasure Island. Treasure I ...

最新文章

  1. 视障人士体验自动驾驶:携导盲犬登车,未来有望“自己开”
  2. B站疯传,一整套Java学习资料,白拿不谢,叫我雷锋!
  3. 2021年寒假将至,教育部致信中小学生家长的一封信:人生如长跑,起步忌冲刺,薄发需厚积
  4. Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数)...
  5. 【过程改进】10分钟进阶Nuget
  6. 【吃炸弹的鸽子UVA10765-双联通模板】
  7. 睡眠多少分钟一个循环_睡眠分为几个阶段每个阶段大概多少时间?
  8. 实现机器学习的循序渐进指南VII——Blending Stacking
  9. token什么意思中文_gre是什么意思中文
  10. php -- 目录、路径、磁盘
  11. 使用Opencv分离图像通道/合并图像通道
  12. android 日历 定制,Android自定义View(CustomCalendar-定制日历控件)
  13. 完美手柄震动效果-xbox360手柄模拟器下载
  14. macos sierra_如何在macOS Sierra中恢复“剩余电池时间”
  15. 大学计算机类专业详解,多伦多大学计算机相关专业解析
  16. 电脑技术员联盟 GhostXp Sp3 装机版V5.1
  17. 真香,华为主动离职也给 N+1
  18. 华为大数据云issues
  19. html图片自适应上下左右居中显示,图片大小自适应垂直居中的方法
  20. oracle 用Sqlplus连接的时候中文出现乱码“?胧淙胗没?”的解决方案

热门文章

  1. AutoCAD Civil3D纵断面图中如何修改坡长为变坡点之间的距离
  2. 在阿里当外包,是一种什么工作体验?
  3. 怎么用dos命令进入指定的文件夹
  4. deep deepfm wide 区别_FM算法和DeepFM算法
  5. 华为公司官方指定的五种主流编程语言
  6. JS 获取当前时间及当天零点,当月零点,往前1小时,7天,1个月,1年
  7. twig模板引擎使用php,TWIG模板引擎使用
  8. Java自动化测试调试中遇到的问题
  9. 域名转让或弃用一定要注销备案,否则后患无穷
  10. Kaggle实战:电子游戏销量分析(Vedio Game Sales)