博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 3681 Prison Break
阅读量:6880 次
发布时间:2019-06-27

本文共 3036 字,大约阅读时间需要 10 分钟。

HDU_3681

    由于Y和G加起来不到15个,那么可以预先将F、Y、G之间的最短路处理出来,然后化归成TSP问题来做。

#include
#include
#include
#include
#define MAXD 20int N, M, dis[MAXD][MAXD], g[MAXD][MAXD], mark, Y, G, sx, sy, vis[MAXD][MAXD];int dx[] = {-1, 1, 0, 0}, dy[] = {
0, 0, -1, 1};char b[MAXD][MAXD];int f[1 << 15 | 10][MAXD];void init(){ int i, j; Y = 1; for(i = 1; i <= N; i ++) { scanf("%s", b[i] + 1); for(j = 1; j <= M; j ++) { if(b[i][j] == 'F') g[i][j] = 0, sx = i, sy = j; else if(b[i][j] == 'S') g[i][j] = -1; else if(b[i][j] == 'Y') g[i][j] = Y ++; else if(b[i][j] == 'D') g[i][j] = -2; } } mark = (1 << Y) - 2, G = Y; for(i = 1; i <= N; i ++) for(j = 1; j <= M; j ++) if(b[i][j] == 'G') g[i][j] = G ++;}inline int inside(int x, int y){ return x >= 1 && x <= N && y >= 1 && y <= M;}void dfs(int x, int y){ int i, nx, ny; vis[x][y] = 1; for(i = 0; i < 4; i ++) { nx = x + dx[i], ny = y + dy[i]; if(inside(nx, ny) && !vis[nx][ny] && g[nx][ny] != -2) dfs(nx, ny); }}int check(){ int i, j; memset(vis, 0, sizeof(vis)); dfs(sx, sy); for(i = 1; i <= N; i ++) for(j = 1; j <= M; j ++) if(b[i][j] == 'Y' && !vis[i][j]) return 0; return 1;}void bfs(int sx, int sy){ int i, j, x, y, nx, ny, id = g[sx][sy]; memset(vis, -1, sizeof(vis)); std::queue
q; vis[sx][sy] = 0; q.push(sx * (M + 1) + sy); while(!q.empty()) { x = q.front() / (M + 1), y = q.front() % (M + 1), q.pop(); if(g[x][y] >= 0) dis[id][g[x][y]] = vis[x][y]; for(i = 0; i < 4; i ++) { nx = x + dx[i], ny = y + dy[i]; if(inside(nx, ny) && vis[nx][ny] == -1 && g[nx][ny] != -2) vis[nx][ny] = vis[x][y] + 1, q.push(nx * (M + 1) + ny); } }}int dp(int limit){ int i, j, k; memset(f, -1, sizeof(f)); f[1][0] = limit; for(i = 1; i < (1 << G); i ++) for(j = 0; j < G; j ++) { if(f[i][j] == -1) continue; if((i & mark) == mark) return 1; for(k = 0; k < G; k ++) if((i & 1 << k) == 0 && f[i][j] >= dis[j][k]) { if(k >= Y) f[i | 1 << k][k] = limit; else f[i | 1 << k][k] = std::max(f[i | 1 << k][k], f[i][j] - dis[j][k]); } } return 0;}void solve(){ int i, j; if(Y == 1) { printf("0\n"); return ; } if(!check()) { printf("-1\n"); return ; } memset(dis, 0x3f, sizeof(dis)); for(i = 1; i <= N; i ++) for(j = 1; j <= M; j ++) if(g[i][j] >= 0) bfs(i, j); int min = 0, max = 1000, mid; for(;;) { mid = min + max + 1 >> 1; if(mid == max) break; if(dp(mid)) max = mid; else min = mid; } printf("%d\n", mid);}int main(){ while(scanf("%d%d", &N, &M), N || M) { init(); solve(); } return 0;}

转载地址:http://meubl.baihongyu.com/

你可能感兴趣的文章
RHEL7.2集成安装Nagios4.2.1+Cacti0.8.8h+NPC2.0.4
查看>>
网站样式变黑白的办法
查看>>
360假冒发布系统补丁 微软官方或将介入调查
查看>>
iOS App 主题切换
查看>>
用实验来说明lib的概念及链接方式
查看>>
我的友情链接
查看>>
快速排序思想及实现
查看>>
jQuery事件--- event.preventDefault() 取消点击动作的默认导航行为
查看>>
03LaTeX学习系列之---TeXworks的使用
查看>>
Object Detection-评价标准-AP mAP
查看>>
第一次配置MySQL主主+LVS+Keepalived----有感
查看>>
Oracle用sql语句创建用户,并授权
查看>>
微软的私有云存储协议SMB 3.0的多通道应用
查看>>
解决embed标签设置z-index无效
查看>>
Mysql bin-log日志配置与恢复数据
查看>>
jquery this $(this)
查看>>
xposed hook所有类的所有函数
查看>>
ACM动态规划总结
查看>>
在DNS服务器上如何配置某个域名的指定解析
查看>>
我的友情链接
查看>>