Til the Cows Come Home(poj 2387 Dijkstra算法(单源最短路径))

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 32824   Accepted: 11098

Description

Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible.

Farmer John‘s field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it.

Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.

Input

* Line 1: Two integers: T and N

* Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.

Output

* Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.

Sample Input

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

Sample Output

90

Hint

INPUT DETAILS:

There are five landmarks.

OUTPUT DETAILS:

Bessie can get home by following trails 4, 3, 2, and 1.

Dijkstra算法

1.定义概览

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。

问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)

2.算法描述

1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

2)算法步骤:

a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。

b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。

c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。

d.重复步骤b和c直到所有顶点都包含在S中。

执行动画过程如下图

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 const int INF=99999999;                    //设为无穷大
 7 int maps[1005][1005],v[1005],d[1005];  //v表示是否已经过遍历 d表示从源到点当前最短路
 8 int n;
 9
10 void Dijkstra(int s,int t)
11 {
12     int i,j,k,mini;
13     for(i=1;i<=n;i++)
14         d[i]=INF;                      //除源点设为0距离外 其他先设为无穷大
15     d[s]=0;
16     for(i=1;i<=n;i++)                  //n点循环n次
17     {
18         mini=INF;
19         k=-1;
20         for(j=1;j<=n;j++)              //在所有未标记点中 选d值最小的点
21         {
22             if(!v[j] && d[j]<mini)
23             {
24                 mini=d[k=j];
25             }
26         }
27         v[k]=1;                         //标记节点
28         if(k==t)
29         {
30             printf("%d\n",d[t]);
31             return;
32         }
33         for(j=1;j<=n;j++)
34         {
35             if(!v[j] && d[k]+maps[k][j]<d[j])   //表示从k出发的点,对于所有边,更新相连点
36             {
37                 d[j]=d[k]+maps[k][j];
38             }
39         }
40     }
41 }
42
43 int main()
44 {
45     int T,i,j,x,y,D;
46     while(scanf("%d %d",&T,&n)!=EOF)
47     {
48         memset(v,0,sizeof(v));            //清除标记
49         for(i=1;i<=n;i++)
50         {
51             for(j=1;j<=n;j++)
52             {
53                 maps[i][j]=INF;
54             }
55         }
56         for(i=1;i<=T;i++)
57         {
58             scanf("%d %d %d",&x,&y,&D);
59             if(maps[x][y]>D)               //可能有多条路,只记录最短的
60                 maps[x][y]=D,maps[y][x]=D;
61         }
62         Dijkstra(1,n);
63     }
64     return 0;
65 }                                          //END Thankyou

时间: 2024-10-13 22:52:24

Til the Cows Come Home(poj 2387 Dijkstra算法(单源最短路径))的相关文章

kuangbin专题专题四 Til the Cows Come Home POJ - 2387

题目链接:https://vjudge.net/problem/POJ-2387 题意:从编号为n的城市到编号为1的城市的最短路. 思路:dijkstra模板题,直接套板子,代码中我会带点注释给初学者看. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <string> 6 using namespac

hdu 2680 最短路径(dijkstra算法+多源最短路径单源化求最小值)

Choose the best route Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7062    Accepted Submission(s): 2301 Problem Description One day , Kiki wants to visit one of her friends. As she is liable

数据结构与算法--单源最短路径算法之dijkstra

单源最短路径之dijkstra算法 最优子问题:dis(s,...,e)是s到e的最短路径,在这条路径上的所有点之间dis(pi,pj)距离是最小的. 算法思路: 首先初始化,dis[s][i]是s到i的距离,直接相连的就是其距离,不直接相连的就是无穷大 下面是算法主要模块: 1.选取dis[i]最小的点加入到P{S}中, 2.计算是否更新dis[j],j是和i直接相连的 3.重复以上步骤,直到e

Dijkstra求解单源最短路径

Dijkstra(迪杰斯特拉)单源最短路径算法 Dijkstra思想 Dijkstra是一种求单源最短路径的算法. Dijkstra仅仅适用于非负权图,但是时间复杂度十分优秀. Dijkstra算法主要思想是: 主要思想是,将结点分成两个集合:已确定最短路长度的,未确定的. 一开始第一个集合里只有节点V. 然后重复这些操作: 1.对那些刚刚被加入第一个集合的结点的所有出边执行松弛操作. 2.从第二个集合中,选取一个最短路长度最小的结点,移到第一个集合中. 用暴力算法的时间复杂度是Ο(n2+m)

Dijkstra算法 --- 单源最短路

Dijkstra算法适用于边权值为正的情况,可用于计算正权图上的单元最短路. 其伪代码如下: 设d[v0] = 0, 其他d[i] = INF 循环n次{ 在所有未标号的结点中,选取d值最小的结点x 给结点x加上永久标号 对于从x出发的所有边,执行松弛操作. } //松弛操作的伪代码如下: RELAX(u,v,w) if(u.d + w(u,v) < v.d){ v.d = w.d + w(u,v); pre[v] = u; } Dijkstra算法代码: /* Dijkstra 单源最短路算法

P103 Dijkstra算法 单源最短路问题优化算法

///标准的dijkstra算法 void dijkstra() { while(true) { int vert=-1; dis[-1]=INF; for(int i=0;i<num_v;i++) { if( (!used[i]) && ( vert==-1||dis[i]<dis[vert] ) ) {vert=i;} } if(vert==-1) break;///这里要提前break;好像是这样... used[vert]=1; for(int i=0;i<num

A - Til the Cows Come Home POJ - 2387

Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible. Farmer John's field ha

数据结构:单源最短路径--Dijkstra算法

Dijkstra算法 单源最短路径 给定一带权图,图中每条边的权值是非负的,代表着两顶点之间的距离.指定图中的一顶点为源点,找出源点到其它顶点的最短路径和其长度的问题,即是单源最短路径问题. Dijkstra算法 求解单源最短路径问题的常用方法是Dijkstra(迪杰斯特拉)算法.该算法使用的是贪心策略:每次都找出剩余顶点中与源点距离最近的一个顶点. 算法思想 带权图G=<V,E>,令S为已确定了最短路径顶点的集合,则可用V-S表示剩余未确定最短路径顶点的集合.假设V0是源点,则初始 S={V

Dijkstra单源最短路径

Dijkstra单源最短路径 给定一个带权有向图G=(V,E) ,其中每条边的权是一个非负实数.另外,还给定 V 中的一个顶点,称为源.现在我们要计算从源到所有其他各顶点的最短路径长度.这里的长度是指路上各边权之和.这个问题通常称为单源最短路径问题. 下面给出两个计算单源最短路径的模板. Dijkstra_简化版:时间复杂度O(n^2),不可处理重边图 //计算图的以s点为起点的单源最短路径 //图中节点从1到n编号 //运行dijkstrea之前,需要先把图中两点间的距离保存在dist[i][