题意:一张网格图,多组数据,输入n,m,sx,sy,tx,ty大小,起终点

接下来共有2n-1行,奇数行有m-1个数,表示横向的边权,偶数行有m个数,表示纵向的边权

样例输入:

4  4  1  1  4  4

10 10 10

9 0 0 10

0 0 0

9 0 0 10

0 9 0 10

0 9 9

2 2 1 1 2 2

0

1 1

0

0 0 0 0 0 0

样例输出:

Case 1:  100

Case 2:  Impossible

我们发现此题的特点在于允许转向,也就是说我们可以将转向的状态利用一维表示出来以进行转移

同时由于起终点也需要*2,我们干脆新开两维,一维表示是否*2,另一维表示当前已经操作后面对的方向

利用spfa进行转移即可

  1. #include<bits/stdc++.h>
  2. #define rep(i,x,y) for(register int i=x;i<=y;i++)
  3. using namespace std;
  4. const int NN=;
  5. const int NNN=;
  6. const int inf=;
  7. inline int read(){
  8. int x=,f=;char ch=getchar();
  9. while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
  10. while(isdigit(ch)){x=(x<<)+(x<<)+(ch^);ch=getchar();}
  11. return x*f;}
  12.  
  13. int g[NN][];
  14. int d[NNN];
  15. bool vis[NNN];
  16.  
  17. int dx[]={,,,-};
  18. int dy[]={,-,,};
  19.  
  20. int n,m,sx,sy,tx,ty,x,y,t,idx,w;
  21. struct node{int x,y,t;};queue<node> q;
  22.  
  23. inline int calc(int x,int y){return (x-)*m+(y-);}
  24. inline int calc(int x,int y,int t){return calc(x,y)*+t;}
  25. bool check(int x,int y){return <=x&&x<=n&&<=y&&y<=m;}
  26.  
  27. int main(){
  28. while(scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&tx,&ty)!=EOF&&n&&m){
  29.  
  30. rep(i,,*n-)
  31. if(i&) rep(y,,m-){
  32. x=(i+)/,w=read();if(!w) w=inf;
  33. g[calc(x,y)][]=g[calc(x,y+)][]=w;}
  34. else rep(y,,m){
  35. x=i/,w=read();if(!w) w=inf;
  36. g[calc(x,y)][]=g[calc(x+,y)][]=w;}
  37. //t代表的状态是身后已经加的边的状态
  38.  
  39. memset(d,,sizeof d);
  40. d[calc(sx,sy,)]=;
  41. vis[calc(sx,sy,)]=;
  42. q.push((node){sx,sy,});
  43.  
  44. while(!q.empty()){
  45. x=q.front().x;
  46. y=q.front().y;
  47. t=q.front().t;q.pop();
  48. vis[calc(x,y,t)]=;
  49.  
  50. // 4 前后都要二倍
  51. if(t<){// i-i
  52. int xx=x+dx[t],yy=y+dy[t];
  53. if(!check(xx,yy)) continue;
  54. int w=g[calc(x,y)][t];
  55. if(d[calc(xx,yy,t)]>d[calc(x,y,t)]+w){
  56. d[calc(xx,yy,t)]=d[calc(x,y,t)]+w;
  57. if(!vis[calc(xx,yy,t)])
  58. vis[calc(xx,yy,t)]=,q.push((node){xx,yy,t});}
  59. w=w*;//i-4
  60. if(d[calc(xx,yy,)]>d[calc(x,y,t)]+w){
  61. d[calc(xx,yy,)]=d[calc(x,y,t)]+w;
  62. if(!vis[calc(xx,yy,)])
  63. vis[calc(xx,yy,)]=,q.push((node){xx,yy,});}
  64. }else{
  65. for(int i=;i<=;i++){
  66. int xx=x+dx[i],yy=y+dy[i];
  67. if(!check(xx,yy)) continue;
  68. int w=g[calc(x,y)][i]*; //4 是转向所以w跟随i变化
  69. // 4-i
  70. if(d[calc(xx,yy,i)]>d[calc(x,y,t)]+w){
  71. d[calc(xx,yy,i)]=d[calc(x,y,t)]+w;
  72. if(!vis[calc(xx,yy,i)])
  73. vis[calc(xx,yy,i)]=,q.push((node){xx,yy,i});}
  74. // 4-4
  75. if(d[calc(xx,yy,)]>d[calc(x,y,t)]+w){
  76. d[calc(xx,yy,)]=d[calc(x,y,t)]+w;
  77. if(!vis[calc(xx,yy,)])
  78. vis[calc(xx,yy,)]=,q.push((node){xx,yy,});
  79. }
  80. }
  81. }/*
  82. i-i 正常直走
  83. i-4 决策 转弯的第一条边
  84. 到达终点
  85. 4-i 决策 转弯的第二条边
  86. 起点结束
  87. 4-4 决策 转弯到终点
  88. 决策 连续转弯
  89. */
  90. }// 三维状态 二维权值
  91. int ans=d[calc(tx,ty,)];
  92. if(ans>=inf) printf("Case %d: Impossible\n",++idx);
  93. else printf("Case %d: %d\n",++idx,ans);
  94. }return ;
  95. }

完结撒花

模拟赛20181015 Uva1078 bfs+四维dp的更多相关文章

  1. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  2. 「模拟赛20190327」 第二题 DP+决策单调性优化

    题目描述 小火车虽然很穷,但是他还是得送礼物给妹子,所以他前往了二次元寻找不需要钱的礼物. 小火车准备玩玩二次元的游戏,游戏当然是在一个二维网格中展开的,网格大小是\(n\times m\)的,某些格 ...

  3. 【noip模拟赛7】上网 线性dp

    描述 假设有n个人要上网,却只有1台电脑可以上网.上网的时间是从1 szw 至 T szw ,szw是sxc,zsx,wl自创的时间单位,至于 szw怎么换算成s,min或h,没有人清楚.依次给出每个 ...

  4. 【noip模拟赛5】任务分配 降维dp

    描述 现有n个任务,要交给A和B完成.每个任务给A或给B完成,所需的时间分别为ai和bi.问他们完成所有的任务至少要多少时间. 输入 第一行一个正整数n,表示有n个任务.接下来有n行,每行两个正整数a ...

  5. 2017-5-14 湘潭市赛 Similar Subsequence 分析+四维dp+一些简单优化

    Similar Subsequence Accepted : Submit : Time Limit : MS Memory Limit : KB Similar Subsequence For gi ...

  6. (计数器)NOIP模拟赛(神奇的数位DP题。。)

    没有原题传送门.. 手打原题QAQ [问题描述]     一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,…,9.其中—个页码不含多余的0,如N=1234时第5页不是00 ...

  7. codehunter 「Adera 6」杯省选模拟赛 网络升级 【树形dp】

    直接抄ppt好了--来自lyd 注意只用对根判断是否哟留下儿子 #include<iostream> #include<cstdio> using namespace std; ...

  8. 「模拟赛20191019」B 容斥原理+DP计数

    题目描述 将\(n\times n\)的网格黑白染色,使得不存在任意一行.任意一列.任意一条大对角线的所有格子同色,求方案数对\(998244353\)取模的结果. 输入 一行一个整数\(n\). 输 ...

  9. 「模拟赛20191019」A 简单DP

    题目描述 给一个\(n\times m\)的网格,每个格子上有一个小写字母. 对于所有从左上角\((1,1)\)到右下角\((n,m)\)只向下或向右走的路径构成的集合,判断是否存在两条走法不同的路径 ...

随机推荐

  1. Vcenter 账户密码过期设置修改

    Vcenter 安装完后,账户的密码过期时间是90天,如果不进行修改90天后就会过期,不能登录,这样对日常的定时任务影响比较大. 如何进行修改呢? 对于Vcenter 6.0 ,修改密码过期设置只能使 ...

  2. C# -- 使用线程池 ThreadPool 执行多线程任务

    C# -- 使用线程池 ThreadPool 执行多线程任务 1. 使用线程池 class Program { static void Main(string[] args) { WaitCallba ...

  3. 记录Nginx作为静态资源web服务场景配置

    server { listen   80; server_name    localhost; sendfile    on; access_log    /var/log/nginx/host.ac ...

  4. Ubuntu 16.04.1 LTS配置LNMP使用wordpress搭建博客

    今天想用wordpress搭个博客,我的服务器是腾讯云的,然后腾讯云里有官方文档搭建的,但它是用centos为例, 搞得我的ubuntu跟着它走了些歪路,然后结合网上其它资料,终于一点一点的解决了. ...

  5. 云计算openstack共享组件(2)——Memcache 缓存系统

    一.缓存系统 在大型海量并发访问网站及openstack等集群中,对于关系型数据库,尤其是大型关系型数据库,如果对其进行每秒上万次的并发访问,并且每次访问都在一个有上亿条记录的数据表中查询某条记录时, ...

  6. 二、Redis安装

    一.下载Redis: 下载地址:https://github.com/MSOpenTech/redis/releases. 由于redis并不支持window系统,而window版本的redis的是由 ...

  7. windows 平台使用 VS2017 编译openssl源码

    windows 平台使用 VS2017 编译openssl源码 1)依赖安装 安装 perl 脚本解释器 下载 http://libevent.net/download 安装 nasm 汇编器 C:\ ...

  8. 拒绝回调,拥抱async await

    之前使用jquery中ajax,请求的结果需要写在回调函数里面,后面接触到了axios/fetch,使用了es6中Promise进行封装,这种链式结构调用,看起来比之前直观,可是还是没有解决回调的问题 ...

  9. cetos6.8配置svn服务器

    一,安装步骤 1,  检查是否安装过svn rpm -qa subversion 2,  卸载旧版本svn yum remove subversion 3,  安装SVN,输入官网提供的命令 yum ...

  10. 前端js日期时间格式转换

    前端前后端接口处理时经常会遇到需要转换不同时间格式的情况,比如时间戳格式转换成正常日期显示来进行前端展示. 下面是分享一些不同格式的日期转换函数方法. /** * 时间戳转时间 * @param {S ...