HDNOIP201404最短路径
难度级别: A; 编程语言:不限;运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

a、b、c是3个互不相等的1位正数,用它们和数字0可以填满一个n行n列的方格阵列,每格中都有4种数码中的一个。填入0的格子表示障碍物,不能属于任何路径。你是否能找出一条从1行1列出发,到达n行n列且代价最小的路径呢?注意:每一格只能走向与之相邻的上、下、左、右的非0且不出界的格子。而所谓路径代价指的是路径经过的所有格子中的数字总和。请你编程求出从1行1列的位置出发到达n行n列的最小路径代价,若无法到达就输出-1。

输入
第一行输入数字n。
接下来的n行每行是一个长度为n的数字串,这n个字符串就构成了一个数字符的方阵。方阵中除了'0'外,最多还可以包含3种数字符。
输出
仅有最小代价或-1这一个整数。
输入示例
【输入样例1】
4
1231
2003
1002
1113
【输入样例2】
4
3150
1153
3311
0530
输出示例
【输出样例1】
10
【输出样例2】
-1
其他说明
60%的数据,n<10,80%的数据,n<100,100%的数据,n<1000
 

确实是一道好题。

1000*1000的最短路可能有些吃力,实测卡时1000s+。那么怎么做呢?

方阵中除了'0'外,最多还可以包含3种数字符。

这提醒我们,可以在这上面做些文章。考虑为什么用Heap来优化Dijkstra,是因为有些边很长有些边很短,对于所有入边相同的点,易得它们的距离是递增的。

算法就水落石出了,用3个单调队列代替Heap,注意每次如何取队头和如何加入队尾。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
char A[maxn][maxn];
int n,d[maxn][maxn],vis[maxn][maxn],idx[maxn],tp;
struct Point {
int x,y;
bool operator < (const Point& ths) {return d[x][y]<d[ths.x][ths.y];}
};
queue<Point> q[];
int getfront() {
int c=-;
if(q[].size()) c=;
if(q[].size()&&(c<||q[].front()<q[c].front())) c=;
if(q[].size()&&(c<||q[].front()<q[c].front())) c=;
return c;
}
int mx[]={,-,,},my[]={,,,-};
int solve() {
if(A[][]==''||A[n][n]=='') return -;
q[idx[A[][]]].push((Point){,});d[][]=A[][]-'';
while(q[].size()+q[].size()+q[].size()) {
int t=getfront();int x=q[t].front().x,y=q[t].front().y;q[t].pop();
if(x==n&&y==n) return d[x][y];
if(vis[x][y]) continue;vis[x][y]=;
rep(dir,,) {
int nx=x+mx[dir],ny=y+my[dir];
if(nx>=&&nx<=n&&ny>=&&ny<=n&&A[nx][ny]!=''&&d[x][y]+A[nx][ny]-''<d[nx][ny]) {
d[nx][ny]=d[x][y]+A[nx][ny]-'';
q[idx[A[nx][ny]]].push((Point){nx,ny});
}
}
}
return -;
}
int main() {
n=read();
rep(i,,n) scanf("%s",A[i]+);
memset(idx,-,sizeof(idx));
rep(i,,n) rep(j,,n) {
if(idx[A[i][j]]<&&A[i][j]!='') idx[A[i][j]]=tp++;
d[i][j]=<<;
}
printf("%d\n",solve());
return ;
}

HDNOIP201404最短路径的更多相关文章

  1. COJ 0244 HDNOIP201404最短路径

    HDNOIP201404最短路径 难度级别: A: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 a.b.c是3个互不相等的1 ...

  2. Johnson 全源最短路径算法

    解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...

  3. Floyd-Warshall 全源最短路径算法

    Floyd-Warshall 算法采用动态规划方案来解决在一个有向图 G = (V, E) 上每对顶点间的最短路径问题,即全源最短路径问题(All-Pairs Shortest Paths Probl ...

  4. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  5. Bellman-Ford 单源最短路径算法

    Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...

  6. 最短路径算法-Dijkstra

    Dijkstra是解决单源最短路径的一般方法,属于一种贪婪算法. 所谓单源最短路径是指在一个赋权有向图中,从某一点出发,到另一点的最短路径. 以python代码为例,实现Dijkstra算法 1.数据 ...

  7. bzoj 4016: [FJOI2014]最短路径树问题

    bzoj4016 最短路路径问题 Time Limit: 5 Sec Memory Limit: 512 MB Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点 ...

  8. 51nod 1459 迷宫游戏 (最短路径—Dijkstra算法)

    题目链接 中文题,迪杰斯特拉最短路径算法模板题. #include<stdio.h> #include<string.h> #define INF 0x3f3f3f3f ],v ...

  9. C++迪杰斯特拉算法求最短路径

    一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...

随机推荐

  1. shell中常用的命令方法

    <1>Linux Shell 脚本中字符串的连接方法 [root@localhost company]# var1=/etc/[root@localhost company]# var3= ...

  2. 【转】Solr5.3.1定时增量添加索引和重做索引

    本文转自:https://code.google.com/p/solr-dataimport-scheduler/ Solr Data Import Hander Scheduler 说明:Solr官 ...

  3. HDU1009老鼠的旅行 (贪心算法)

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  4. MFC 线程

    //新开一个线程去处理新的工作,可以传一个参数 class MyClass//自定义一个类 { void fun(){} ... } MyClass* myObject=new MyClass;Afx ...

  5. Mysql 5.6.17-win64.zip配置

    第一大步:下载. a.俗话说:“巧妇难为无米之炊”嘛!我这里用的是 ZIP Archive 版的,win7 64位的机器支持这个,所以我建议都用这个.因为这个简单嘛,而且还干净. 地址见图 拉倒最下面 ...

  6. Java并发编程:Synchronized及其实现原理

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  7. hadoop机架感知

    背景 分布式的集群通常包含非常多的机器,由于受到机架槽位和交换机网口的限制,通常大型的分布式集群都会跨好几个机架,由多个机架上的机器共同组成一个分布式集群.机架内的机器之间的网络速度通常都会高于跨机架 ...

  8. php 的函数参数值类型限定

    如例: function test(array $a,test $b){ /*...*/ } class test{ /*...*/ } test(array(),new test); 表示test函 ...

  9. PHP生成不重复随机数的方法

    无论是Web应用,还是WAP或者移动应用,随机数都有其用武之地.在最近接触的几个小项目中,我也经常需要和随机数或者随机数组打交道,所以,对于PHP如何产生不重复随机数常用的几种方法小结一下. 方法一: ...

  10. 深入理解 KVC\KVO 实现机制 — KVC

    KVC和KVO都属于键值编程而且底层实现机制都是isa-swizzing,所以本来想放在一起讲的.但是篇幅有限所以就分成了两篇博文 KVO实现机制传送门 KVC概述 KVC是Key Value Cod ...