zzuli 2187 我觉得自己跑得很快 (Dijkstra + 链式前向星)
来源:互联网 发布:钓鱼台工作 知乎 编辑:程序博客网 时间:2024/04/30 06:27
传送门
某大佬zyf出的神题
Description
As we all know, the… 算了,我英语不好,题目很简单,我们有一个N层的数字塔,塔上每一个格子都有一个bad值,下图展示了一个N=4的数字塔:
当我们进入某个格子时就会获得对应的bad值,我们每次只能向下或者向右下移动一个格子。等等,当时讲动态规划用的不就是这个例题,我还记得它的状态转移方程,这是不是太easy了?
那好吧,来增加一点点难度,我们每次不仅可以向下,向右下移动,还可以向左或者向右移动一个格子,但是不能越界。一开始我们的ssh学长在第一行第一列,他想走到最后一行,但是我们的ssh学长不喜欢bad,他想使得走到最后一行时获得的bad值的和最小,当然最后一行的bad值也要算上。
现在他把这个问题交给你,想让你计算出他最小能获得多少bad值,以及他获得最小bad值时是位于最后一行的哪一列。
Input
第一行一个整数N(1<=N<=1000)。
接下来N行,第i行有i个整数wi1 wi2 … wii,wij表示第i行第j列的格子对应的bad值。
Output
一行两个整数,第一个整数是最小的bad值的和,第二个整数是ssh学长最后的位置,只需要输出该位置是第N行的第几列即可。如果答案不唯一,输出列编号最小的位置。
Sample Input
4
1
2 2
3 4 5
4 5 6 7
Sample Output
10 1
HINT
Source
看上去是dp,实际是最短路,,,好像有人dp过了,把每二位点用(i-1)* + j转成点,然后把边连上,脑洞挺大。。不过用读入优化的时候要考虑空格的问题,因为数据每行最后多一个空格
代码如下:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<vector>#include<string>#include<algorithm>#include<queue>using namespace std;const int MAX = 1000010;const int INF = 0x3f3f3f3f;int num[MAX],head[MAX],N;//直接把点的权值存放到num里面struct Edge{ int to,cost; int next;};struct Edge rng[4*MAX];int cnt;void add(int u,int v){ rng[cnt].to = v; rng[cnt].next = head[u]; head[u] = cnt++;}int dis[MAX];typedef pair<int,int> P;struct Rule{ bool operator()(const int &a,const int &b) const{ return dis[a] > dis[b]; }};void Dijkstra(){ priority_queue<int,vector<int>,Rule> q;//这里最好重载下吧,我用pair的时候用greater会超时 fill(dis+1,dis+1+N*N,INF); dis[1] = num[1]; q.push(1); while(!q.empty()){ int x = q.top();q.pop(); for(int k=head[x];k != -1;k = rng[k].next){ int to = rng[k].to; if(dis[to] > dis[x] + num[to]){ dis[to] = dis[x] + num[to]; q.push(to); } } }}int main(void){ scanf("%d",&N); memset(head,-1,sizeof(head)); int u,v; for(int i=1;i<=N;i++){ for(int j=1;j<=i;j++){ scanf("%d",&num[(i-1)*N+j]); u = (i-1)*N + j;//合并与其相连的四个点 if(j > 1){ v = (i-1)*N + j-1; add(u,v); } if(j < i){ v = (i-1)*N + j+1; add(u,v); } v = i*N + j; add(u,v); v = i*N + j+1; add(u,v); } } Dijkstra(); int f = -1,c = -1; for(int i=(N-1)*N+1;i<=N*N;i++){ if(f == -1 || dis[i] < dis[f]){ f = i; c = i - (N-1)*N; } } printf("%d %d\n",dis[f],c);}
- zzuli 2187 我觉得自己跑得很快 (Dijkstra + 链式前向星)
- 【zzuli 1925 信道安全】+ 链式前向星
- zzuli 2130 hipercijevi bfs + 链式前向星 + 输入外挂
- HDU1874 畅通工程续 【链式前向星】+【Dijkstra】
- dijkstra队列优化链式前向星(C++、Java)
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 链式前向星
- 云主机搭建并配置web服务器
- JavaScript语法学习2--运算符、流程控制语句
- PHP简单的生成器使用
- 阿里四面面经
- 美容美发美甲店做活动效果提升30%的营销方案18个套路
- zzuli 2187 我觉得自己跑得很快 (Dijkstra + 链式前向星)
- 算法应用题之今日头条的还该出多少道题?
- List集合
- Python高阶进程3--网络编程
- C++之面向对象编程学习笔记
- 高并发基础之volatile(二)
- 使用PHP中内置的服务器
- jar包冲突引起的反思
- MySQL学习图文笔记整理(二):多表操作