zoukankan      html  css  js  c++  java
  • 贪心算法《最短路径》

    题目大意:

          存在几个城市1~n;每个城市任意连向其他城市。并且,路程也是不尽相同的。若从一个城市出发,去各个城市,则去各个城市每一个城市的最短路程计算出来。

    如下是几个城市的地图:

    题目分析:一个城市可能有多个路径,但是寻找最小的路径却不容易。

    算法:贪心算法:从1城市出发,到达4和5城市最小路径的充分必要条件是到达前面每一个城市都是最短路径——及贪心算法中局部最优解,构成全局最优解

    数据结构:用map[][]这样的矩阵记录每个城市的路的大小。dist[]记录每个城市的最短路程。p[]记录前一个城市,这样就能找到全部路线。flag[]记录

    每个城市是否找到最短的路程。免得重复查找。

    1.初始化部分

    void init(int map[][Max], int dist[], int p[], bool flag[])
    {
     cin >> n;
     for (int i = 0; i <= n; i++)
     {
      p[i] = -1;
      flag[i] = false;  //当flag为假时,则还不为最短路程
      dist[i] = Maxnum;
      for (int j = 0; j <= n; j++)
      {
       map[i][j] = Maxnum;
      }
     }
     //操作
     p[1] = 0;
     dist[1] = 0;
     map[1][1] = 0;
     flag[1] = true;
    }

    将map[][]内全部初始化为极大的数

    注意:在这里先让1城市带入了。

    2.输入块儿

    void cinfun(int map[][Max], int dist[], int p[], bool flag[])
    {
     cin >> m;
     //数据的输入
     int num = m;
     while (num--)
     {
      int u, k, l;
      cin >> u >> k >> l;
      map[u][k] = l;
     }
    }

    3.寻找在flag[]为假中dist[]的最小的城市。并,找到与他相连的城市。比较相连城市的目前的dist[]去该城市的dist[]加上这两个城市的距离。

    若小,则说明走该城市到相连城市是更短的路径。(核心!!!!)

    void minfun(int map[][Max], int dist[], int p[], bool flag[])
    {
     for (int i = 2; i <= n; i++)
     {
      if (dist[i] > map[1][i])
      {
       dist[i] = map[1][i];
       p[i] = 1;
      }
     }
     m--;
     while (m--)
     {
      //算法:在V_S中寻找最小路径x。
      int min = 0;
      for (int i = 1; i <= n; i++)
      {
       if (dist[i] < dist[min]&&!flag[i]) min = i;
      }
      //通过dis[k]>dist[x]+map[x][k]时改变该路程
      for (int i = 1; i <= n; i++)
      {
       if (!flag[i])
       {
        if (map[min][i] != Maxnum)
        {
         if (dist[i] > dist[min] + map[min][i])
         {
          dist[i] = dist[min] + map[min][i];
          p[i] = min;
         }
        }
       }
      }
      flag[min] = true;
     }
    }

    代码如下:

    #include<iostream>
    using namespace std;
    //数据结构Map记录路线情况,
    //dist[]记录最短路径,
    //q[]记录前驱,
    //flag[]记录是否为已经是最短路径
    #define Max 100
    #define Maxnum 1000
    int map[Max][Max];
    int dist[Max], p[Max];
    bool flag[Max];
    int n;
    int m;
    void init(int map[][Max], int dist[], int p[], bool flag[]);
    void cinfun(int map[][Max], int dist[], int p[], bool flag[]);
    void minfun(int map[][Max], int dist[], int p[], bool flag[]);
    int main()
    {
     //初始化
     init(map, dist, p, flag);
     //输入数据
     cinfun(map, dist, p, flag);
     //最小值
     minfun(map, dist, p, flag);
     for (int i = 1; i <= n; i++)
     {
      cout << "城市:" << i << "前一个城市:" << p[i] << endl;
      cout << "最短路程是:" << dist[i] << endl << endl;
     }
     return 0;
    }

    void init(int map[][Max], int dist[], int p[], bool flag[])
    {
     cin >> n;
     for (int i = 0; i <= n; i++)
     {
      p[i] = -1;
      flag[i] = false;  //当flag为假时,则还不为最短路程
      dist[i] = Maxnum;
      for (int j = 0; j <= n; j++)
      {
       map[i][j] = Maxnum;
      }
     }
     //操作
     p[1] = 0;
     dist[1] = 0;
     map[1][1] = 0;
     flag[1] = true;
    }
    void cinfun(int map[][Max], int dist[], int p[], bool flag[])
    {
     cin >> m;
     //数据的输入
     int num = m;
     while (num--)
     {
      int u, k, l;
      cin >> u >> k >> l;
      map[u][k] = l;
     }
    }

    void minfun(int map[][Max], int dist[], int p[], bool flag[])
    {
     for (int i = 2; i <= n; i++)
     {
      if (dist[i] > map[1][i])
      {
       dist[i] = map[1][i];
       p[i] = 1;
      }
     }
     m--;
     while (m--)
     {
      //算法:在V_S中寻找最小路径x。
      int min = 0;
      for (int i = 1; i <= n; i++)
      {
       if (dist[i] < dist[min]&&!flag[i]) min = i;
      }
      //通过dis[k]>dist[x]+map[x][k]时改变该路程
      for (int i = 1; i <= n; i++)
      {
       if (!flag[i])
       {
        if (map[min][i] != Maxnum)
        {
         if (dist[i] > dist[min] + map[min][i])
         {
          dist[i] = dist[min] + map[min][i];
          p[i] = min;
         }
        }
       }
      }
      flag[min] = true;
     }
    }

  • 相关阅读:
    闲记
    网络数据校验随笔(1)
    [转载]各种在线api地址
    WebLogic Server
    接口和抽象类的区别
    PowerBuilder连接数据库
    Entity Framework(实体框架 EF)
    SQL Server附加数据库提示“版本为661,无法打开,支持655版本……”
    实习总结
    此页状态无效,可能已损坏
  • 原文地址:https://www.cnblogs.com/damaoranran/p/8617695.html
Copyright © 2011-2022 走看看