hihocoder(1081)最短路径1

Dijkstra,基础题,借此题好好地复习了之前的算法,Dijkstra是贪心算法的最好例子。

总结一下,Dijkstra算法是将顶点分为两组,一组S表示已经找到最短路径的顶点集合,一组Q表示还未确定是最短路径的顶点集合,维护一个D[n]的数组来记录顶点src到每个顶点的最短路径,该数组在算法完成之前或到达目标顶点前所保存的只是当前情况下的最短路径,当算法完成跳出循环后,D[i]代表点src到点i的最短距离。

算法的过程就是不断更新D[n]数组的过程,首先初始化D[n]为无限大,并将起点src加入集合S,将D[s]设为0,扫描所有与src邻接的点j,并更新D[j]=min(D[j],D[src]+len(src,j)),这个操作一般称作为release(松散操作)。接着从Q中D[i]最小的顶点找出来放入S,继续执行上一步类似的操作,进入循环,直到Q为空。

这时D中保存即为最短路径的值。如果希望记录最短路径,那么可以再维护一个前缀数组P[n]。

这是一基本的Dijkstra算法,算法复杂度O(n2)但是可以通过堆优化算法,使得算复杂度降低到O((m+n)*logn)。

下面直接贴一下堆优化的算法:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <queue>
 5 using namespace std;
 6
 7 #define IFINITY 0x7fffffff
 8 #define MAXN 100005
 9
10 int D[MAXN];
11 bool Qv[MAXN];
12 int N, M, S, T;
13 vector<pair<int, int>> Map[MAXN];
14
15 int Dijkstra() {
16     priority_queue<pair<int, int>> q;
17
18     for (int i = 1; i <= N; ++i) D[i] = IFINITY;
19
20         D[S] = 0;
21     q.push(make_pair(-D[S], S));
22
23     while (!q.empty()) {
24         int u = q.top().second; q.pop();
25         if (u==T) break;
26         if (Qv[u]) continue;
27         Qv[u] = true;
28
29         for (int i = 0; i < Map[u].size(); ++i) {
30                         int uvLen, v;
31             v = Map[u][i].first;
32             uvLen = Map[u][i].second;
33             if (D[v] > D[u] + uvLen) {
34                 D[v] = D[u] + uvLen;
35                 q.push(make_pair(-D[v], v));
36             }
37         }
38     }
39
40     return D[T];
41 }
42
43 int main()
44 {
45     int u, v, length;
46     scanf("%d%d%d%d", &N, &M, &S, &T);
47     for (int i = 1; i <= M; ++i) {
48         scanf("%d%d%d", &u, &v, &length);
49         Map[u].push_back(make_pair(v, length));
50         Map[v].push_back(make_pair(u, length));
51     }
52
53     printf("%d\n", Dijkstra());
54     return 0;
55 }                

时间: 2024-10-11 13:34:21

hihocoder(1081)最短路径1的相关文章

Hihocoder #1081 最短路径一 dijkstra

#1081 : 最短路径·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的早上,小Hi和小Ho在经历了一个小时的争论后,终于决定了如何度过这样有意义的一天——他们决定去闯鬼屋! 在鬼屋门口排上了若干小时的队伍之后,刚刚进入鬼屋的小Hi和小Ho都颇饥饿,于是他们决定利用进门前领到的地图,找到一条通往终点的最短路径. 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点

hihoCoder - 1081 - 最短路径&#183;一 (dijkstra算法!!)

#1081 : 最短路径·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的早上,小Hi和小Ho在经历了一个小时的争论后,终于决定了如何度过这样有意义的一天--他们决定去闯鬼屋! 在鬼屋门口排上了若干小时的队伍之后,刚刚进入鬼屋的小Hi和小Ho都颇饥饿,于是他们决定利用进门前领到的地图,找到一条通往终点的最短路径. 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点

hihoCoder#1081 最短路径&#183;一

原题地址 Dijkstra算法,甚至都不用优化(堆或优先队列)即可过 代码: 1 #include <iostream> 2 #include <vector> 3 #include <set> 4 #include <cstring> 5 6 using namespace std; 7 8 #define MAX_POINT 1024 9 #define MAX_EDGE 16384 10 11 int N, M, S, T; 12 int graph[

#1081 : 最短路径&#183;一 hihocoder dijstra http://ideone.com/H6g4MS

dijstra 顺带回顾下      http://ideone.com/H6g4MS dijstra:  n点 m边 起点s 终点t  平均每个点m/n条边 1 遍历n找到  未使用的 距离起点最近的点p     O(n) 开始的时候p=s dist[p]=0 2 如果p为终点,输出dist[p]作为结果.      O(1) 3 用p更新与p距离最近的n个点   O(m/n) 4 标记p为已经使用的点 回到步骤1      O(1) 1~4最多循环O(n)次 开销O(nn) #include

hihoCoder - 1089 - 最短路径&#183;二:Floyd算法 (floyd算法!!)

#1089 : 最短路径·二:Floyd算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的中午,小Hi和小Ho在吃过中饭之后,来到了一个新的鬼屋! 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路. 由于没有肚子的压迫,小Hi和小Ho决定好好的逛一逛这个鬼屋,逛着逛着,小Hi产生了这样的问题:鬼屋中任意两个地点之间的最短路径是多少呢? 提示:其实如果你开心

hihoCoder - 1093 - 最短路径&#183;三:SPFA算法 (SPFA)

#1093 : 最短路径·三:SPFA算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋! 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路. 不过这个鬼屋虽然很大,但是其中的道路并不算多,所以小Hi还是希望能够知道从入口到出口的最短距离是多少? 提示:Super Programming Festiv

hihoCoder#1089 最短路径&#183;二:Floyd算法

原题地址 感觉Floyd算法比Dijkstra还要简单.. 唯一需要注意的是,初始的距离默认值不要设过大,否则溢出就不好了,根据题意,只要大于10^3即可 代码: 1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 #define MAX_POINT 1024 7 #define MAX_EDGE 16384 8 9 int N, M; 10 int d[MAX_POINT][MAX_POI

它们其实都是“图”

2018-11-05 19:37:25 图是表示一些事物或者状态的关系表达方法.由于许多问题都可以归约为图的问题,人们提出了许多和图相关的算法.因此,在程序设计竞赛中有许多需要直接或者间接对图进行处理或者间接用图解决的问题. 一.图是什么 图由顶点(vertex)和边(edge)组成.一般来说,可以把图分成两类.边没有指向性的称为无向图,边具有指向性的称为有向图. 无向图 两个顶点之间如果有边连接,那么就视为两点相邻.相邻顶点的序列称为路径.起点和终点重合的路径称为圈.任意两点之间都有路径连接的

# 1089 最短路径&#183;二:Floyd算法 hihocoder http://ideone.com/R8ixAH

floyd算法回顾         http://ideone.com/R8ixAH 只需要一个矩阵保持最短距离: 假设n各节点. 1  枚举每个节点t 作为中间节点,也称作松弛节点   O(n) { 2  枚举每个开始节点i  O(n) {        3 枚举每个结束结束节点j    O(n) { 判断当前已知的i到j的距离是否比经过t节点长,如果是,修改ij距离.O(1) } } 开销是O(n*n*n) #include<iostream> #include<vector>