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)所有,转载请保留原地址! [试题]为了简化城市公共汽车收费系 ...
随机推荐
- 问题:IIS部署 MVC项目 (autofac) 错误解决
http://www.cnblogs.com/yelaiju/p/3375168.html Could not load file or assembly 'System.Core, Version= ...
- qrcode.react和jquery.qrcode生成二维码
qrcode.react 1.安装 npm install qrcode.react 2.用法(这里用的ant design) import React from 'react'; import QR ...
- window下安装多个tomcat
解压该压缩包,生成3分tomcat 分别命名为 tomcat1,tomcat2,tomcat3 进入tomcat1/conf/目录,修改server.xml 进入tomcat1/bin目录,修改 se ...
- The input stream is not a valid binary format.
The input stream is not a valid binary format. The starting contents (in bytes) are: 53-79-73-74-65- ...
- Webdriver中关于driver.navigate().to()和driver.get()使用的区别
先是有一个父页上button弹开一个子页,总共有4个子页,必须前一个页上的必填信息录完,才能在这个页面触发下一个子页. 用driver.navigate().to(baseUrl2),直接跳转到第2个 ...
- Local Databases with SQLiteOpenHelper
Overview For maximum control over local data, developers can use SQLite directly by leveraging SQLit ...
- 【HDU 1599】 Find the mincost route
[题目链接] 点击打开链接 [算法] 弗洛伊德求最小环模板 我们知道,在一个环上,一定有一个有且仅有一个编号最大的点,设这个点为k,起点为i,终点为j,那么 mincost = dist[i][j] ...
- P4455 [CQOI2018]社交网络
这个题仔细一看就是生成树计数,但是我这个记性是真的差,早就忘了.复习了一下高斯消元,然后这个题就是很裸的题了. ps:高斯消元解行列式的时候要取反. 题干: 题目背景 当今社会,在社交网络上看朋友的消 ...
- poj 3281 Dining【最大流】
记得把牛拆掉!拆成两个点i和i'在中间连一条流量为1的边,来限制每头牛只能选一组 一般来讲是一种物品一个消费者各占一边,但是这里有两个物品,所以考虑把牛放在中间,s向所有的食物连流量为1的边,所有食物 ...
- Python Flask 实现移动端应用接口(API)
引言 目前,Web 应用已形成一种趋势:业务逻辑被越来越多地移到客户端,逐渐完善为一种称为富互联网应用(RIA,rich Internet application)的架构.在 RIA 中,服务器的主要 ...