最短路径(Dijkstra,SPFA,Floyd)

Dijkstra:

HDU2066:

题意:每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。

输出草儿能去某个喜欢的城市的最短时间。

6 2 3

1 3 5

1 4 7

2 8 12

3 8 4

4 9 12

9 10 2

1 2

8 9 10

9

#include<iostream>

using namespace std;

const int maxn = 1000 + 10;

const int INF = 0x3fffffff;

int map[maxn][maxn];

int T;

int S;

int D;

int dis[maxn];

bool used[maxn];

void init()

{

         memset(used,0,sizeof(used));

         int i;

         int j;

         for(i=0; i<maxn; i++)                //初始化map都为无穷

         {

                   dis[i] = INF;

                   for(j=0; j<maxn; j++)

                   {

                            map[i][j] = INF;

                   }

         }

}

void dijkstra(){

         dis[0] = 0;

         int i;

         for(i=0; i<maxn; i++){

                   int j;

                   int min = INF;

                   int min_j = -1;

                   for(j=0; j<maxn; j++){                //找出当前最优的点

                            if(!used[j] && min > dis[j]){

                                     min = dis[j];

                                     min_j = j;

                            }

                   }

                   if(min_j == -1){                    //不存在最优点时结束

                            return ;

                   }

                   used[min_j] = true;                  //将最优点标志为用过

                   for(j=0; j<maxn; j++){

                            if(!used[j] && dis[j] > dis[min_j] + map[min_j][j]) {    //没有访问过并且当初值比之前对应的dis值要小,就更新该值

                                     dis[j] = dis[min_j] + map[min_j][j];

                            }

                   }

         }

}

int main()

{

         while(cin>>T>>S>>D)

         {

                   init();

                   int i;

                   for(i=0; i<T; i++)

                   {

                            int a;

                            int b;

                            int values;

                            cin>>a>>b>>values;

                            if(map[a][b] > values)      //无向时为map[a][b] = map[b][a];有向时分别输入map[a][b],map[b][a]

                            {

                                     map[a][b] = map[b][a] = values;

                            }

                   }

                   for(i=0; i<S; i++)                             //开始的城市的值为0

                   {

                            int begin;

                            cin>>begin;

                            map[0][begin] = 0;

                            map[begin][0] = 0;

                   }

                   dijkstra();

                  

                   int mincost = INF;

                   for(i=0; i<D; i++)           //找出想去中的最优路径

                   {

                            int ans;

                            cin>>ans;

                            if(mincost > dis[ans])

                            {

                                     mincost = dis[ans];

                            }

                   }

                   cout<<mincost<<endl;

         }

         return 0;

}

SPFA:

思路:不是枚举所有节点,而是通过队列来进行优化 设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止

int SAFP(int start,int n){

 queue<int>Q;

 dis[0] = 0;

 vist[start] = true;

 Q.push (start);                //将初始点压入队列

 while(!Q.empty()){

  int t;

  t = Q.front ();

  Q.pop ();

  for(int i=1; i<=n; i++){

      if(dis[t] + map[t][i] < dis[i]){

       dis[i]=dis[t] + map[t][i];

       if(!vist[i]){

        vist[i]=true;

        Q.push (i);

        cnt[i]++;

       }

      }

  }

  vist[t]=false;

  if(cnt[t]>=n)              //有环时结束循环

      return -1;

 }

}

Floyd:

void floyd(){                             //时间复杂度为o(n * n * n),推导过程还不明白

    for(int k=1; k<=n; k++){

        for(int i=1; i<=n; i++){

            for(int j=1; j<=n; j++){

                if(map[i][j] > map[i][k] + map[k][j]){

                   map[i][j] = map[i][k] + ?map[k][j];

                }

            }

        }

    }

}

原文地址:https://www.cnblogs.com/cbyniypeu/p/3388773.html