裸裸的spfa~嘿嘿嘿!

裸裸的spfa~嘿嘿嘿!

spfa全名:shortest path faster algorithm ,又是一个国内神犇写的算法。

目的:一个图图,之后求图图从起点到终点的最短路径长度。

这种算法在效率上呢。!你不能质疑神犇的算法效率!但是这个算法不是很稳定。当然这种算法在稀疏图上是特别长脸的,而在稠密图反正是有不乐观的一面。spfa算法有一种动态逼近的味道。:设立一个队列来保持它等待优化的队列(存的点),(这个队列很重要,毕竟有很多优化都是从这个点开始拓展的。)每次取出队列的头,对以头为起点的各个边的终点进行一次松弛操作。能松弛就入队。一直等到队列都出完。就说明整个图解决问题。取最后一个点上的值就是最优值。

 

/*松弛操作:是一种对当前节点以前存的值和其它路径走来的值的比较。取优值。

举一个简单的栗子:

现在的这个小小的图。b上面存的是它由a到b的路径上的所有值的和。之后呢。a又从c又从c走到b了。发现这条路比刚才a直接到b的值要优。所以呢/把b上的值换成1+3=4.这样从a走到b的路径就是优的。而这个操作。就叫松弛。为什么叫这个呢。tmd我也不知道。

*/

 

之后。开始举一个强大的图示来表现spfa的算法。前方高能!!!

首先,我在百度百科上随便找了个图。嗯。这个图非常经典。

 

起点就是a 那这个图的终点就是g,

初始化。所有点上的值,都是最大值。之后好松弛啊啊啊啊。

 

首先。从起点开始

设立一个队列,来表示要等待去松弛点的队列。(很像BFS)

之后,又有一个数组来表示从起点到这个点的最短路径。/最优路径也可以/

a先进队,之后开始对a接下来的点进行操作。

a有 b c d

之后发现,从a开始a上面的值+ab这条路的值要比原先大;就松一松它。松弛。

b上的值变成24 

同理,c上的值边成8  。d上的值变成15   。

!!(重点)让能松弛的点都入队。

队列就变成   a  b  c   d 

之后,把它们都在visit数组上打上标记,表示现在在队列里。

队首出队。变成b  c  d;

a的点的操作就完成了。

 

之后取队首,b

开始对b进行松弛操作

b  的边就是  e

之后对e进行松弛。

松弛成功。

e点上的值就变成了24+6=30;表示现阶段。从a到e最优值就是30

就让e入队。

队列就成了 b  c  d   e

e在visit打上标记。

b出队。

b的操作就结束了。

 

之后取队首, c

从c开始的边  终点有 e  f 

对e进行松弛操作

发现30大于(起点到c的值“8”+ce边“7”)

e上的值就变成了/15

发现e本来就在队列里。不入队了。

对f可以松弛

f的值就变成11.f入队。visit上f打标记。

队列就变成了 c  d  e   f

c出队,

c的操作结束。

 

之后的一直要进行下去。直到队列为空。

嗯,就是这样

 

贴上一道题。poj上的2387;

 

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.

 裸题。

所以就是,spfa。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<queue>
 5 using namespace std;
 6 struct node {
 7     int next;
 8     int v;
 9     int val;
10 }edge[100001];
11 int head[10001],n,m,visit[10001],cnt,d[10001];
12 queue<int> q;
13 void add(int x,int y,int z)
14 {
15     edge[++cnt].v=y;
16     edge[cnt].next=head[x];
17     edge[cnt].val=z;
18     head[x]=cnt;
19 }
20 int main()
21 {
22     int x,y,z;
23     while(scanf("%d%d",&n,&m)==2)
24     {
25     memset(head,-1,sizeof(head));
26     memset(d,214546,sizeof(d));
27     memset(visit,0,sizeof(visit));
28     while(!q.empty() ){
29         q.pop() ;
30     }
31     for(int i=1;i<=n;i++)
32     {
33         scanf("%d%d%d",&x,&y,&z);
34         add(x,y,z);
35         add(y,x,z);
36     }
37     q.push(1);
38     visit[1]=1;
39     d[1]=0;
40     while(!q.empty())
41     {
42         int a=q.front();
43         q.pop();
44         visit[a]=0;
45         for(int i=head[a];i!=-1;i=edge[i].next)
46         {
47             if(d[edge[i].v]>d[a]+edge[i].val)
48               {
49                   if(!visit[edge[i].v]){
50                       d[edge[i].v]=d[a]+edge[i].val;
51                       q.push(edge[i].v);
52                       visit[edge[i].v]=1;
53                   }
54                   else {
55                       d[edge[i].v]=d[a]+edge[i].val;
56                   }
57               }
58         }
59     }
60     printf("%d ",d[m]);
61      }
62     return 0;
63 }

 

posted @ 2016-09-12 13:08  刺猬的玻璃心碎了  阅读(725)  评论(0编辑  收藏  举报