boj 454 帮帮小叮当【SPFA】
题目链接:http://code.bupt.edu.cn/problem/p/454/
454. 帮帮小叮当
题目描述
小叮当刚刚学会了传送门的使用方法,可是它不小心跌落到二维空间一个 n * m 的矩阵格子世界的入口(1,1)处,
他得知出口在(n,m)处,每穿越一个格子门,它的体力值会下降。
又饿又累的他 IQ 已经降为负数了,聪明的你,能帮他规划一下路线,使得它体力值下降的最少吗?
每一行有且仅有一个传送门,但是小叮当上课睡着了,只学会了用传送门瞬移到相邻行的另一个传送门且耗 1 滴体力。
此外,他就只能通过格子门走到相邻四个格子中的一个,也耗 1 滴体力。
ps,由于符合的路径太多了,你只需要告诉我们体力值消耗最小值。
输入格式
每组数据,第一行给 n,m 两个整数(2 <= n,m <= 10000),接下来一行,有 n 个数字,代表该行传送门的位置 x( 1 <= x <= m )。以 n,m 都为0结束。Mays温馨提醒:数据组数略大于100。
输出格式
对每组输入,输出一行,体力消耗最小值。
输入样例
5 5
5 4 3 2 1
0 0
输出样例
8
刚开始看这道题,不知道怎么解,后来听大牛们说,此题可以抽象成如下图:
五角星代表传送阵,圆圈代表起点和终点。由于要求最小的距离,那么,除了样例给出的极端情况以外,走传送门一定是可以节省体力的,那么,以起点到各传送门,传送门到传送门,传送门到终点建边,而边的权值为两点间的曼哈顿距离,传送门之间的边的权值都为1,。之后求出最短路径即可。
之前图论基础几乎为0....这次第一次用SPFA,解出来还是挺开心的^_^
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#define N 400100
using namespace std;
struct edge
{int from,to,c,nxt;
}e[N];
int head[N];
int d[N];
int s;
bool vis[N];
int n,m;
int dist(int x,int y,bool S)
{if(S)return abs(x-1)+abs(y-1);elsereturn abs(x-n)+abs(y-m);
}
void spfa(int s)
{queue<int> q;memset(d,0x3f,sizeof(d));d[s]=0;memset(vis,0,sizeof(vis));q.push(s);vis[s]=1;while(!q.empty()){int x=q.front();q.pop();vis[x]=0;for(int k=head[x];k!=-1;k=e[k].nxt){if(d[e[k].to]>d[e[k].from]+e[k].c){d[e[k].to]=d[e[k].from]+e[k].c;if(!vis[e[k].to]){vis[e[k].to]=1;q.push(e[k].to);}}}}}
int main()
{while(~scanf("%d%d",&n,&m)&&(n||m)){memset(head,-1,sizeof(head));int t=1,last;for(int i=0;i<4*n-2;){int temp;scanf("%d",&temp);e[i].from=0;e[i].to=t;e[i].c=dist(t,temp,1);e[i].nxt=head[0];head[0]=i++;e[i].from=t;e[i].to=n+1;e[i].c=dist(t,temp,0);e[i].nxt=head[t];head[t]=i++;if(i!=2){e[i].from=t;e[i].to=t-1;e[i].c=1;e[i].nxt=head[t];head[t]=i++;e[i].from=t-1;e[i].to=t;e[i].c=1;e[i].nxt=head[t-1];head[t-1]=i++;}t++;}spfa(0);printf("%d\n",d[n+1]);}return 0;
}
下面是dijkstra的代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#define N 400100
using namespace std;
struct dij
{int id,dist;bool operator < (const dij s1) const{return dist>s1.dist;}
};
struct edge
{int from,to,c,nxt;
}e[N];
priority_queue<dij> q;
int head[N];
int d[N];
int s;
bool vis[N];
int n,m;
void dijkstra()
{memset(vis,0,sizeof(vis));while(!q.empty()) q.pop();for(int i=0;i<n+2;i++) d[i]=99999999;d[0]=0;dij ss,tt;ss.id=0;ss.dist=0;vis[ss.id]=true;q.push(ss);while(!q.empty()){tt=q.top();q.pop();int id=tt.id,dist=tt.dist;vis[id]=true;for(int k=head[id];k!=-1;k=e[k].nxt){if(!vis[e[k].to] && d[e[k].to]>d[id]+e[k].c){d[e[k].to]=d[id]+e[k].c;ss.id=e[k].to;ss.dist=d[e[k].to];q.push(ss);}}}
}
int dist(int x,int y,bool S)
{if(S)return abs(x-1)+abs(y-1);elsereturn abs(x-n)+abs(y-m);
}
//void spfa(int s)
//{
// queue<int> q;
// memset(d,0x3f,sizeof(d));
// d[s]=0;
// memset(vis,0,sizeof(vis));
//
// q.push(s);
// vis[s]=1;
// while(!q.empty())
// {
// int x=q.front();
// q.pop();
// vis[x]=0;
// for(int k=head[x];k!=-1;k=e[k].nxt)
// {
// if(d[e[k].to]>d[e[k].from]+e[k].c)
// {
// d[e[k].to]=d[e[k].from]+e[k].c;
// if(!vis[e[k].to])
// {
// vis[e[k].to]=1;
// q.push(e[k].to);
// }
// }
// }
// }
//
//}
int main()
{while(~scanf("%d%d",&n,&m)&&(n||m)){memset(head,-1,sizeof(head));int t=1,last;for(int i=0;i<4*n-2;){int temp;scanf("%d",&temp);e[i].from=0;e[i].to=t;e[i].c=dist(t,temp,1);e[i].nxt=head[0];head[0]=i++;e[i].from=t;e[i].to=n+1;e[i].c=dist(t,temp,0);e[i].nxt=head[t];head[t]=i++;if(i!=2){e[i].from=t;e[i].to=t-1;e[i].c=1;e[i].nxt=head[t];head[t]=i++;e[i].from=t-1;e[i].to=t;e[i].c=1;e[i].nxt=head[t-1];head[t-1]=i++;}t++;}dijkstra();printf("%d\n",d[n+1]);}return 0;
}
boj 454 帮帮小叮当【SPFA】相关推荐
- Asce's Summer Ranking No.7
作为Mays学姐的脑残粉,还是用一发ym来镇这篇文章~ 大Mays平时无处不在卖萌(见前几期的题),可一旦秀起智商来,出的数论题我们都跟不上她思路0.0 A. 暑假作业题 2014新生暑假个人排位赛0 ...
- 2014 BUPT 新生排位赛07
A 暑假作业题 链接:http://code.bupt.edu.cn/problem/p/469/ 大致题意:见题目 思路:就是一个比较繁琐的模拟,个人感觉思路还挺清晰的.我的方法是先分成亿来处理, ...
- HDU 2112 HDU Today lt;SPFA算法+map函数gt;
HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- ACM学习历程—HDU 2112 HDU Today(map spfa 优先队列)
Description 经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候,XHD夫妇也退居了二线 ...
- 杭电2112(SPFA)
HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 程序设计——第七周作业(Floyd:胜负未知场数;dijkstra:猫猫快线最快线路;SPFA:城市收税)
A-胜负未知场数 题目描述 众所周知,TT 有一只魔法猫. 这一天,TT 正在专心致志地玩<猫和老鼠>游戏,然而比赛还没开始,聪明的魔法猫便告诉了 TT 比赛的最终结果.TT 非常诧异,不 ...
- HDOJ 2112 HDU Today (最短路 Dijkstra SPFA)
HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HFUT-1360 单身晚会 【SPFA】
Description ZJ和ZCX在一起很久了,两个人都互生爱意,最终决定喜结良缘,从此踏入浪漫的婚姻殿堂. 但是,ZJ的好基友们想到以后ZJ就不能经常跟他们一起愉快的玩耍了,都觉得非常伤心难过, ...
- 图论 --- spfa + 链式向前星 (模板题) dlut 1218 : 奇奇与变形金刚
1218: 奇奇与变形金刚 Time Limit: 3 Sec Memory Limit: 128 MB Submit: 130 Solved: 37 [Submit][Status][Web B ...
- [复习]Dijkstra+堆/SPFA/Dijkstra+优先队列 浣花溪公园
题目背景 最短路模板题目.SPFA 或 用堆优化的迪杰斯特拉算法均可实现. 题目描述 成都浣花溪公园是一座有着诗歌文化气息的公园,它以杜甫草堂的历史文化内涵为背景,运用现代园林和建筑设计的前沿理论,以 ...
最新文章
- 使用KiWi Syslog Daemon构建日志服务器
- linux把目录下的文件设置属性为rx,LINUX的文件属性与目录配置
- 浙江工商大学计算机学院调剂录取,浙江工商大学2017年硕士研究生调剂拟录取名单公布(持续更新)...
- python之collections之有序字典(OrderedDict)
- 工作188:表单校验规则
- matlab基础试题,MATLAB基础试题题目及答案,课程2020最新期末考试题库,章节测验答案...
- C语言对结构体何时用- , 何时用.
- 伪指令endp告诉汇编程序_第2章 指令系统及汇编语言程序设计 题库和答案
- OpenCVQt学习之一——打开图片文件并显示
- VS2012下基于Glut glRotatef glTranslatef示例程序:
- 微软宣布以197亿美元现金收购语音识别巨头Nuance
- 全民营销,只看这篇文章就够了
- oracle 递归用法,oracle递归用法
- yolov5s-6.0网络模型结构图
- 微信小程序开发者账号注册以及开发者工具的使用
- 发布文章出现请勿使用默认标题
- C++900行代码实现中国象棋游戏规则以及相关功能
- 联想潮5000 BIOS 解锁 CFG Lock
- Linux 浏览器访问PHP显示源码
- 使用 JSONPath 解析 JSON内容 详细