题目大意:
存在几个城市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;
}
}