UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
题意:
给一个由n*m个正方形格子组成的矩形,其中每个格子的边都是可以走的,长度给定,规定:如果在进入该路前需要拐弯,或者走完该路需要拐弯,都是需要付出双倍距离的(每条路最多算2倍)。问从起点到终点的最短路经长。
思路:
这个题目超级难搞,思路很简单,就是很麻烦!!!我将1个点4个方向的路长都记录下来,然后进行最短路,只要一个点的某个方向更新了,就进队。所有都考虑得差不多了,就是WA。。。
步骤 :
(1)起点不进队,因为起点出发都需要双倍,况且,如果起点路长为0的话,其他点就不能路过起点了,所以将起点能更新到的点进队,并更新他们的路长,而起点路长仍然是INF。
(2)对于用一个点来更新别人,可以更新相邻4个方向的点,而更新某一个方向的点又可以用当前点的4个方向来更新它。
(3)一旦被更新的点是终点,就更新答案(出来也要双倍)。因为路径可能经过终点多次再折返从终点出来会更近。
(4)所以边注意不能算2倍以上。
#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL unsigned long long
#define up 0
#define right 1
#define down 2
#define left 3
using namespace std;
const int N=;
int n, m, a, sx, sy, ex, ey;
int g[N][N][]; //0从12点钟开始,顺时针走
int dist[N][N][]; //记录来自4个方向的距离
int tag[N][N][]; //标记4个值是否已经翻倍了
int inq[N][N];
int ans;
bool ok(int x, int y)
{
if(x>&&x<=n && y>&&y<=m) return true;
else return false;
}
void isinq(deque<pii> &que, int x,int y)
{
if(!inq[x][y]) que.push_back(make_pair(x,y));
inq[x][y]=;
} void isend(int x,int y)
{
if(x==ex && y==ey)
{
if(dist[x][y][up]<INF)
ans=min(ans, dist[x][y][up]+(-tag[x][y][up])*g[x][y][down]);
if(dist[x][y][down]<INF)
ans=min(ans, dist[x][y][down]+(-tag[x][y][down])*g[x][y][up]);
if(dist[x][y][left]<INF)
ans=min(ans, dist[x][y][left]+(-tag[x][y][left])*g[x][y][right]);
if(dist[x][y][right]<INF)
ans=min(ans, dist[x][y][right]+(-tag[x][y][right])*g[x][y][left]);
}
} void init_start(deque<pii> &que)
{
int x=sx;
int y=sy;
if(ok(x-,y) && g[x][y][up] ) //上0
{
dist[x-][y][up] = *g[x][y][up] ;
tag[x-][y][up]=; //拐弯了,已经翻倍
isinq(que, x-, y );
isend(x-,y);
}
if(ok(x+,y) && g[x][y][down] ) //下2
{
dist[x+][y][down] = *g[x][y][down];
tag[x+][y][down]=;
isinq(que, x+, y );
isend(x+,y);
}
if(ok(x,y-) && g[x][y][left] ) //左3
{
dist[x][y-][left] = *g[x][y][left];
tag[x][y-][left]=;
isinq(que, x, y-);
isend(x,y-);
}
if(ok(x,y+) && g[x][y][right] ) //右1
{
dist[x][y+][right] = *g[x][y][right];
tag[x][y+][right]=;
isinq(que, x, y+);
isend(x,y+);
} } void spfa()
{
deque<pii> que;
init_start(que); while(!que.empty())
{
int x=que.front().first;
int y=que.front().second;
que.pop_front();
inq[x][y]=;
//每个点有4个方向
if(ok(x-,y) && g[x][y][up] ) //上0
{
if(dist[x][y][up]<INF && dist[x-][y][up]> dist[x][y][up] + g[x][y][up]) //上->上
{
dist[x-][y][up]= dist[x][y][up] + g[x][y][up];
tag[x-][y][up]=; //直走的,不计
isinq(que, x-, y );
}
if(dist[x][y][right]<INF && dist[x-][y][up]> dist[x][y][right] + (-tag[x][y][right])*g[x][y][left] + *g[x][y][up] ) //右->上
{
dist[x-][y][up]= dist[x][y][right] + (-tag[x][y][right])*g[x][y][left] + *g[x][y][up];
tag[x-][y][up]=; //拐弯了,已经翻倍
isinq(que, x-, y );
}
if(dist[x][y][left]<INF && dist[x-][y][up]> dist[x][y][left] + (-tag[x][y][left])*g[x][y][right] + *g[x][y][up] ) //左->上
{
dist[x-][y][up]= dist[x][y][left] + (-tag[x][y][left])*g[x][y][right] + *g[x][y][up];
tag[x-][y][up]=; //同上
isinq(que, x-, y );
}
if(dist[x][y][down]<INF && dist[x-][y][up]> dist[x][y][down] + (-tag[x][y][down])*g[x][y][up] + *g[x][y][up] ) //下-上
{
dist[x-][y][up]= dist[x][y][down] + (-tag[x][y][down])*g[x][y][up] + *g[x][y][up];
tag[x-][y][up]=;
isinq(que, x-, y);
}
isend(x-,y);
}
if(ok(x+,y) && g[x][y][down] ) //下2
{
if(dist[x][y][down]<INF && dist[x+][y][down] > dist[x][y][down] + g[x][y][down] ) //下->下
{
dist[x+][y][down] = dist[x][y][down] + g[x][y][down];
tag[x+][y][down]=;
isinq(que, x+, y );
}
if(dist[x][y][right]<INF && dist[x+][y][down] > dist[x][y][right] + (-tag[x][y][right])*g[x][y][left] + *g[x][y][down] ) //右->下
{
dist[x+][y][down] = dist[x][y][right] + (-tag[x][y][right])*g[x][y][left] + *g[x][y][down];
tag[x+][y][down]=;
isinq(que, x+, y );
}
if(dist[x][y][left]<INF && dist[x+][y][down] > dist[x][y][left] + (-tag[x][y][left])*g[x][y][right] + *g[x][y][down] ) //左->下
{
dist[x+][y][down] = dist[x][y][left] + (-tag[x][y][left])*g[x][y][right] + *g[x][y][down];
tag[x+][y][down]=;
isinq(que, x+, y);
}
if(dist[x][y][up]<INF && dist[x+][y][down] > dist[x][y][up] + (-tag[x][y][up])*g[x][y][down] + *g[x][y][down] ) //上-下
{
dist[x+][y][down] = dist[x][y][up] + (-tag[x][y][up])*g[x][y][down] + *g[x][y][down];
tag[x+][y][down]=;
isinq(que, x+, y);
}
isend(x+,y);
}
if(ok(x,y-) && g[x][y][left] ) //左3
{
if(dist[x][y][left]<INF && dist[x][y-][left] > dist[x][y][left] + g[x][y][left] ) //左->左
{
dist[x][y-][left] = dist[x][y][left] + g[x][y][left];
tag[x][y-][left]=;
isinq(que, x, y-);
}
if(dist[x][y][down]<INF && dist[x][y-][left] > dist[x][y][down] + (-tag[x][y][down])*g[x][y][up] + *g[x][y][left] ) //下->左
{
dist[x][y-][left] = dist[x][y][down] + (-tag[x][y][down])*g[x][y][up] + *g[x][y][left];
tag[x][y-][left]=;
isinq(que, x, y-);
}
if(dist[x][y][up]<INF && dist[x][y-][left] > dist[x][y][up] + (-tag[x][y][up])*g[x][y][down] + *g[x][y][left] ) //上->左
{
dist[x][y-][left] = dist[x][y][up] + (-tag[x][y][up])*g[x][y][down] + *g[x][y][left];
tag[x][y-][left]=;
isinq(que, x, y-);
}
if(dist[x][y][right]<INF && dist[x][y-][left] > dist[x][y][right] + (-tag[x][y][right])*g[x][y][left] + *g[x][y][left] ) //右-左
{
dist[x][y-][left] = dist[x][y][right] + (-tag[x][y][right])*g[x][y][left] + *g[x][y][left];
tag[x][y-][left]=;
isinq(que, x, y-);
}
isend(x,y-);
}
if(ok(x,y+) && g[x][y][right] ) //右1
{
if(dist[x][y][right]<INF && dist[x][y+][right] > dist[x][y][right] + g[x][y][right] ) //右->右
{
dist[x][y+][right] = dist[x][y][right] + g[x][y][right];
tag[x][y+][right]=;
isinq(que, x, y+);
}
if(dist[x][y][down]<INF && dist[x][y+][right] > dist[x][y][down] + (-tag[x][y][down])*g[x][y][up] + *g[x][y][right] ) //下->右
{
dist[x][y+][right] = dist[x][y][down] + (-tag[x][y][down])*g[x][y][up] + *g[x][y][right];
tag[x][y+][right]=;
isinq(que, x, y+);
}
if(dist[x][y][up]<INF && dist[x][y+][right] > dist[x][y][up] + (-tag[x][y][up])*g[x][y][down] + *g[x][y][right] ) //上->右
{
dist[x][y+][right] = dist[x][y][up] + (-tag[x][y][up])*g[x][y][down] + *g[x][y][right];
tag[x][y+][right]=;
isinq(que, x, y+);
} if(dist[x][y][left]<INF && dist[x][y+][right] > dist[x][y][left] + (-tag[x][y][left])*g[x][y][right] + *g[x][y][right] ) //左-右
{
dist[x][y+][right] = dist[x][y][left] + (-tag[x][y][left])*g[x][y][right] + *g[x][y][right];
tag[x][y+][right]=;
isinq(que, x, y+);
}
isend(x,y+);
}
}
} int cal()
{
memset(dist, 0x7f, sizeof(dist));
memset(tag, , sizeof(tag));
memset(inq, , sizeof(inq));
ans=INF;
spfa();
return ans==INF? : ans;
} int main()
{
//freopen("input.txt", "r", stdin);
int Case=;
while(scanf("%d %d %d %d %d %d", &n, &m, &sx, &sy, &ex, &ey), n+m+sx+sy+ex+ey)
{
memset(g, , sizeof(g));
for(int x=; x<n; x++) //行号
{
for(int y=; y<m; y++) //列号
{
scanf("%d", &a);
g[x][y][right]=a; //右边1
g[x][y+][left]=a; //左边3
}
for(int y=; y<=m; y++)
{
scanf("%d", &a);
g[x][y][down]=a; //下2
g[x+][y][up]=a; //上0
}
}
for(int y=; y<m; y++)
{
scanf("%d", &a);
g[n][y][right]=a; //右
g[n][y+][left]=a; //左
} int aa=cal();
if(aa) printf("Case %d: %d\n",++Case, aa);
else printf("Case %d: Impossible\n", ++Case);
}
return ;
}
WA代码
UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。的更多相关文章
- UVaLive 4128 Steam Roller (多决策最短路)
题意:给定一个图,r 根横线, c 根竖线.告诉你起点和终点,然后从起点走,每条边有权值,如果是0,就表示无法通行.走的规则是:如果你在下个路要转弯,会使这段路的时间加倍,但是如果一条路同时是这样,那 ...
- UVALive 4128 Steam Roller(最短路(拆点,多状态))
题意:模拟了汽车的行驶过程,边上的权值为全速通过所消耗的时间,而起步(从起点出发的边).刹车(到终点结束的边).减速(即将拐弯的边).加速(刚完成拐弯的边)这四种不能达到全速的情况,消耗的时间为权值* ...
- UVa1078 Steam Roller——拆点+最短路
题目链接 思路 把每个点拆成\(5\)个点\(id(x,y),id(x,y)+n,id(x,y)+2*n,id(x,y)+3*n,id(x,y)+4*n\),分别表示到这个点时的方向为上,右,下,左和 ...
- POJ-2253.Frogger.(求每条路径中最大值的最小值,最短路变形)
做到了这个题,感觉网上的博客是真的水,只有kuangbin大神一句话就点醒了我,所以我写这篇博客是为了让最短路的入门者尽快脱坑...... 本题思路:本题是最短路的变形,要求出最短路中的最大跳跃距离, ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 Description After going through the receipts from your car trip ...
- POJ-1797Heavy Transportation,最短路变形,用dijkstra稍加修改就可以了;
Heavy Transportation Time Limit: 3000MS Memory Limit: 30000K Description Background Hugo ...
- HDOJ find the safest road 1596【最短路变形】
find the safest road Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- HN0I2000最优乘车 (最短路变形)
HN0I2000最优乘车 (最短路变形) 版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址! [试题]为了简化城市公共汽车收费系 ...
随机推荐
- 普通用户无法登陆SSH问题
Linux正常情况下普通用户是可以登陆SSH的,除非系统管理员作了修改,如果没有修改的情况无法登陆可以尝试以下方法解决: 步骤/方法 1 查看 /etc/ssh/sshd_config文件 发现 ro ...
- DataTables warning requested unknown parameter
This is possibly the most cryptic warning message that DataTables will show. It is a short error mes ...
- 记一次部署java项目的问题
项目里面有自动化任务, tomcat 错误信息 Table 'xxx.QRTZ_TRIGGERS' doesn't exist 提示在mysql中找不到这个表. 但mysql中确实存在,但名字是:qr ...
- eclipse中jsp页面乱码问题
若上述位置均改为utf-8之后,页面展示扔为乱码,检查jsp页面是否有编码说明
- uoj 30 tourists
题目大意: 一个无向图 每个点有权值 支持两个操作 1 修改某个点的权值 2 查询a-b所有简单路径的点上的最小值 思路: 可以把图变成圆方树 然后树链剖分 维护 对于每个方点使用可删堆维护 #inc ...
- mysql数据恢复失败记录
今天遇到了MySQL有几个数据表空间丢失的问题,作为一个外行尝试好久没恢复成功,考虑到只是几个基础数据表,就删除数据表停止服务,删除ibd文件后再创新创建表解决了问题. 近期的一些事让我不像以前一样钻 ...
- luogu4917天守阁的地板
https://www.zybuluo.com/ysner/note/1317548--- 题面 给出\(n\),用所有长为\(a\).宽为\(b\)\((1\leq a,b\leq n)\)的长方形 ...
- 洛谷 P1072 Hankson 的趣味题 —— 质因数分解
题目:https://www.luogu.org/problemnew/show/P1072 满足条件的数 x 一定是 a1 的倍数,b1 的因数,a0/a1 与 x/a1 互质,b1/b0 与 b1 ...
- bzoj4881 线段游戏——上升序列方案数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4881 连题意都转化不了了... 题意是要求从一个数列中选出两个上升序列的方案数: 先判断是否 ...
- Python基础第八天
一.内容