关键词:分层图 状态压缩 最短路径

分层图:现在要求从起点到终点的最优路线,但受到手里拿着哪些钥匙的影响,最优路线不单纯了。因此,决定一个节点、一条边的存在的数中应当增加一个手中拿有钥匙的状态。这样就相当于把一张图按拿有钥匙的状态数分出了很多层。

状态压缩:手中拿有钥匙的状态可以压缩到一个整数中。

最短路径:手中拿有钥匙的状态固定了,在分层图中我们就不再用得着走回头路了。这样就转化成了最短路径问题。

#include <cstdio>
#include <cassert>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std; const int MAX_X = , MAX_Y = , MAX_KEY = , MAX_S = << , INF = 0x3f3f3f3f;
int Dist[MAX_X][MAX_Y][MAX_S];
int Key[MAX_X][MAX_Y];
int Gate[MAX_X][MAX_Y][MAX_X][MAX_Y];
int TotX, TotY;
const int xNext[] = { ,-,,, }, yNext[] = { , ,,-, }; struct Queue
{
int xs[MAX_X*MAX_Y*MAX_S], ys[MAX_X*MAX_Y*MAX_S], ss[MAX_X*MAX_Y*MAX_S];
int head, tail;
Queue() { head = tail = ; }
void push(int x, int y, int s) { xs[tail] = x; ys[tail] = y; ss[tail] = s; tail++; }
void pop() { head++; }
bool empty() { return head == tail; }
int frontX() { return xs[head]; }
int frontY() { return ys[head]; }
int frontS() { return ss[head]; }
}; int Bfs()
{
int ans = INF;
static Queue q;
Dist[][][Key[][]] = ;
q.push(, , Key[][]);
while (!q.empty())
{
int x = q.frontX(), y = q.frontY(), s = q.frontS();
q.pop();
Dist[x][y][s | Key[x][y]] = Dist[x][y][s];
s |= Key[x][y];
for (int p = ; p <= ; p++)
{
int x2 = x + xNext[p], y2 = y + yNext[p];
if (x2 >= && x2 <= TotX && y2 >= && y2 <= TotY &&
Dist[x2][y2][s]==INF &&
(Gate[x][y][x2][y2] == - || s&( << Gate[x][y][x2][y2])))
{
Dist[x2][y2][s] = Dist[x][y][s] + ;
q.push(x2, y2, s);
if (x2 == TotX&&y2 == TotY)
ans = min(ans, Dist[x2][y2][s]);
}
}
}
return ans;
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int totObs, totKeySort, x1, x2, y1, y2, gate, totKey, key;
memset(Gate, -, sizeof(Gate));
memset(Dist, INF, sizeof(Dist));
scanf("%d%d%d%d", &TotX, &TotY, &totKeySort, &totObs);
while (totObs--)
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &gate);
Gate[x1][y1][x2][y2] = Gate[x2][y2][x1][y1] = gate;
}
scanf("%d", &totKey);
while (totKey--)
{
scanf("%d%d%d", &x1, &y1, &key);
if (key >= )
printf("error\n");
Key[x1][y1] |= << key;
}
int ans = Bfs();
if (ans == INF)
printf("-1\n");
else
printf("%d\n", ans);
return ;
}

最新文章

  1. 《编写可维护的JavaScript》——JavaScript编码规范(五)
  2. java System.arraycopy 数组复制和合并
  3. List的Capacity
  4. 火币网api的nodejs实现
  5. ccc 旋转
  6. 蓝牙的AVCTP协议笔记
  7. Java-马士兵设计模式学习笔记-观察者模式-读取properties文件改成单例模式
  8. Check if KeyValuePair exists with LINQ&#39;s FirstOrDefault
  9. 百度UEditor(富文本编辑器)的基础用法
  10. phpstorm配置Xdebug进行调试PHP教程
  11. bootstrap-datetimepicker 时间表箭头不能显示
  12. 通过ant脚本编译打包android工程
  13. uva 357 Let Me Count The Ways(01背包)
  14. AddressSanitizer简介
  15. 学习笔记DL003:神经网络第二、三次浪潮,数据量、模型规模,精度、复杂度,对现实世界冲击
  16. 用panels 制作drupal首页
  17. 【机器学习基础】SVM实现分类识别及参数调优(二)
  18. openstack(Pike 版)集群部署(七)--- Cinder 部署
  19. ios的两种界面跳转方式
  20. We could not complete your iTunes Store request

热门文章

  1. buf.readInt8函数详解
  2. poj3009 Curling 2.0 深搜
  3. index seek和index scan 提高sql 效率
  4. PAT_A1098#Insertion or Heap Sort
  5. Python基础学习(day1)
  6. 终于等到你!微软正式上线 Windows Terminal 预览版
  7. 洛谷P1601 A+B Problem(高精)
  8. Ajax传递的参数如何在浏览器中查看
  9. 使用Linux自带的命令logrotate对Nginx日志进行切割
  10. zabbix监控AIX DB2数据库