贪心算法《最短路径》

题目大意:

      存在几个城市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;
 }
}

 

posted @ 2018-03-21 16:12  神韵袖藏  阅读(1892)  评论(0编辑  收藏  举报