Dijkstra

/*

基本思想就是将所有结点分成两个集合,一个是st所在的集合,另一个是st不在的集合,每次从不包含st的集合中找出一个最优的结点加入到st所在的集合,并更新st到所有不在其所在集合中的点的距离。使用一个visit[]数组来标识结点在哪一个集合中。使用dist[]数组来记录st结点到其他结点的最短路径。

*/

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int const MAXN = 1000;
const int INF = 1000000000;
int g[MAXN][MAXN];
int dist[MAXN];

void Dijkstra(int st,int n)
{

  bool visit[n];

  memset(visit,false,sizeof(visit));

  for(int i = 0; i < n; i++)
  {
        dist[i] = g[st][i];
  }

  visit[st] = true;

  dist[st] = 0;

  for(int i = 0; i < n - 1 ; i++)//只需要n-1次,每次选出一个不再st结点集合中的结点并将
  {                                     //该结点放入到st结点所在的集合中

    int u ;

    int temp = INF;

    for(int j = 0; j < n; j++)//选出一个不在st结点所在集合的最优结点
          {

      if((!visit[j]) && (dist[j] < temp))
      {

        u = j;

        temp = dist[j];

      }
    }

    visit[u] = true;

    //cout<<"U "<<u<<endl;

    for(int k = 0; k < n; k++)//更新与初始结点之间的最短距离
    {
      if((!visit[k]) && (dist[u] + g[u][k] < dist[k]))

      {

        dist[k] = dist[u] + g[u][k];

      }

    }

  }

}
 
int main()
{

  int n,st,ed;

  freopen("dijkstra.txt","r",stdin);

  while(cin >> n)
  {
        memset(g,0,sizeof(g));
        memset(dist,0,sizeof(dist));

      for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
      {
            cin >> g[i][j];
            if(g[i][j] == -1)
                      g[i][j] = INF;
      }
    cin >> st >> ed;
    Dijkstra(st - 1,n);
    cout
<<"st = "<< st << " to ed = " << ed << " : \t"<< dist[ed - 1]<<endl;     //for(int j = 0; j < n; j++) //cout<< dist[j] << " "; //cout<<endl;   }   return 0; }

测试用例:(dijkstra.txt)

4

0 2 -1 4

2 0 3 -1

-1 3 0 2

4 -1 2 0

1 3

原文地址:https://www.cnblogs.com/zhuyp1015/p/2512304.html