图论之最短路径算法

  • dijkstra算法 

    基本思想:某最短路径上的点与源点之间的最短路径必然也在改最短路径之上,采用贪心策略,每次选取当前最短路径即可。

 1 void dijkstra(int n)
 2 {
 3     int num=1,i;
 4     int min,pos;
 5     vis[n]=1;
 6 
 7     while(num<n)//n-1次循环
 8     {
 9         min=MaxInt;
10         for(i=1; i<n; i++)
11             if(vis[i]==0 && dis[i]<min)
12             {
13                 pos=i;
14                 min=dis[i];
15             }
16         vis[pos]=1;
17         dis[pos]=min;
18 
19         for(i=1; i<n; i++)
20             if(vis[i]==0 && dis[i]>dis[pos]+map[pos][i])
21                 dis[i]=min+map[pos][i];//更新权值
22 
23         num++;
24     }
25 }
  • floyd算法

    基本思想:采用动态规划思想,点i,j之间的最短路径要么包含点k,要么不包含点k,选择最小的即可。

 1 void floyd(int n)
 2 {
 3     int i,j,k;
 4     memset(dis,MaxInt,sizeof(dis));
 5 
 6     for(i=1; i<=n; i++)
 7         for(j=1; j<=n; j++)
 8             for(k=1; k<=n; k++)
 9                 if(dis[i][j] > dis[i][k]+dis[k][j] )
10                     dis[i][j] = dis[i][k]+dis[k][j];
11 }
  • spfa算法

    基本思想:spfa算法是bellman-ford算法的队列实现,用dis数组表示点与源点之间的当前最短距离,用数组vis标记点是否在队列中,初始只有源点在队列中,每次取出队头的点v,依次枚举从v出发的边v->u,设边的长度为len,判断Dist[v]+len是否小于Dist[u],若小于则改进Dist[u],并且由于S到u的最短距离变小了,有可能u可以改进其它的点,所以若u不在队列中,就将它放入队尾。这样一直迭代下去直到队列变空,也就是S到所有的最短距离都确定下来,结束算法。若一个点入队次数超过n,则有负权环。

 1 void spfa(int n)
 2 {
 3     int i,temp;
 4 
 5     dis[n]=0;
 6     vis[n]=1;
 7     queue<int> Q;
 8     Q.push(n);
 9 
10     while(!Q.empty())
11     {
12         temp=Q.front(); Q.pop();
13 
14         for(i=1; i<n;i++)
15             if(dis[i]>dis[temp]+map[temp][i])
16             {
17                 dis[i]=dis[temp]+map[temp][i];
18                 if(!vis[i])
19                 {
20                     Q.push(i);
21                     vis[i]=1;
22                 }
23             }
24         vis[temp]=0;
25     }
26 }

  

原文地址:https://www.cnblogs.com/leeshine/p/4317035.html