• 最短路径(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];

                    }

                }

            }

        }

    }

  • 相关阅读:
    【Leetcode】155: 最小栈(Python)
    【深入理解计算机系统】 八:AVR汇编语言
    【深入理解计算机系统】 七:AVR指令集架构
    【深入理解计算机系统】 六:AVR架构和运行环境
    nginx+lua 记一次特殊字符导致"丢包"问题
    python2.7 升级到 python3.6
    神奇的 SQL 之擦肩而过 → 真的用到索引了吗
    神奇的 SQL 之 HAVING → 容易被轻视的主角
    Delphi
    Windows authentication in linux docker container(转发)
  • 原文地址:https://www.cnblogs.com/cbyniypeu/p/3388773.html
Copyright © 2020-2023  润新知