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)所有,转载请保留原地址! [试题]为了简化城市公共汽车收费系 ...
随机推荐
- POJ1182 食物链 —— 种类并查集
题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- python的for...in...if...语句
Python中,for...[if]...语句一种简洁的构建List的方法,从for给定的List中选择出满足if条件的元素组成新的List,其中if是可以省略的.下面举几个简单的例子进行说明. &g ...
- 杂项:IntelliJ IDEA
ylbtech-杂项:IntelliJ IDEA 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http:/ ...
- CodeForces 721A One-dimensional Japanese Crossword (水题)
题意:给定一行字符串,让你输出字符‘B'连续出现的次数. 析:直接扫一下就OK了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024 ...
- E20180318-hm
Scalability 可扩展性 scale n. 规模; 比例(尺); 鱼鳞; 级别; vt. 测量; 攀登; 刮去…的鳞片; vi. 衡量; 攀登; (鳞屑) 脱落; 生水垢; collabor ...
- Swift4 内存管理, 可选链, KeyPath
创建: 2018/03/09 完成: 2018/03/09 参照型数据与ARC ARC ● Swift里, 只有类实例与闭包实例是参照型 ● 生成时参照值为1, 被代入等每次+1, 减少每次-1 ● ...
- 洛谷 P2593 [ZJOI2006]超级麻将【dp】
设f[i][j][k][0/1]表示选到i时,i-1选j张,i选k张,之前选的所有牌是否选择了对子 然后分情况讨论转移即可 #include<iostream> #include<c ...
- poj 1637 Sightseeing tour【最大流+欧拉路】
参考:https://www.cnblogs.com/kuangbin/p/3537525.html 这篇讲的挺好的 首先分清欧拉路和欧拉环: 欧拉路:图中经过每条边一次且仅一次的路径,要求只有两个点 ...
- Canvas 入门案例
五. Canvas 入门案例 1. canvas 圆形绘制 <!DOCTYPE html> <html lang="en"> <head> ...
- Spring的事务传播性与隔离级别以及实现事物回滚
一.事务的四个特性(ACID) 原子性(Atomicity):一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做,要么全部做. 一致性(Consistency): 数据不会因为事务的执行而 ...