根据图的抽象数据类型的定义,使用邻接矩阵实现图的下列算法,并且用c++写出代码。 1、使用普里姆算法生成最小生成树 北 2、使用克鲁斯卡尔算法生成最小生成树 3、求指定顶点到其他各顶点的最短路径 编写测试 main()函数测试算法的正确性 思考问题: 1、最短路径 D 算法,是否可以优化?请写出优化的思路并计算时间复杂度,同时实现 一个新的优化的最短路径算法。
时间: 2024-03-10 07:50:25 浏览: 60
最小生成树之普里姆prim算法C++实现
好的,我会根据您的要求回答问题并提供相应的代码。请注意,代码仅供参考,可能需要根据具体情况进行修改和优化。
1. 普里姆算法(Prim's Algorithm)生成最小生成树
算法思路:从一个顶点开始,每次选择与当前生成树相连的权值最小的边所连接的顶点加入生成树中,直到所有顶点都被加入。
代码实现:
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
int n, m;
int graph[MAXN][MAXN]; //邻接矩阵存储图
int dist[MAXN]; //记录每个顶点与当前生成树的距离
bool visited[MAXN]; //记录每个顶点是否已经加入生成树
void prim(int start)
{
memset(dist, INF, sizeof(dist));
memset(visited, false, sizeof(visited));
dist[start] = 0; //将起点的距离设为0
for (int i = 0; i < n; i++)
{
int u = -1;
for (int j = 0; j < n; j++)
{
if (!visited[j] && (u == -1 || dist[j] < dist[u]))
{
u = j;
}
}
visited[u] = true;
for (int v = 0; v < n; v++)
{
if (!visited[v] && graph[u][v] < dist[v])
{
dist[v] = graph[u][v];
}
}
}
}
int main()
{
cin >> n >> m;
memset(graph, INF, sizeof(graph));
for (int i = 0; i < m; i++)
{
int u, v, w;
cin >> u >> v >> w;
graph[u][v] = graph[v][u] = w;
}
prim(0);
int ans = 0;
for (int i = 0; i < n; i++)
{
ans += dist[i];
}
cout << ans << endl;
return 0;
}
```
2. 克鲁斯卡尔算法(Kruskal's Algorithm)生成最小生成树
算法思路:将所有边按照权值从小到大排序,依次将边加入生成树中,如果这条边的两个端点不在同一个连通块中,则可以加入生成树中。
代码实现:
```c++
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 100;
const int MAXM = 10000;
int n, m;
int father[MAXN]; //并查集数组,用于判断两个顶点是否在同一个连通块中
struct Edge {
int u, v, w;
bool operator < (const Edge& e) const
{
return w < e.w;
}
} edges[MAXM]; //边的结构体数组,用于存储所有边
int find(int x)
{
if (x != father[x])
{
father[x] = find(father[x]);
}
return father[x];
}
void kruskal()
{
sort(edges, edges + m);
for (int i = 0; i < n; i++)
{
father[i] = i;
}
int cnt = 0, ans = 0;
for (int i = 0; i < m; i++)
{
int u = edges[i].u, v = edges[i].v, w = edges[i].w;
int fu = find(u), fv = find(v);
if (fu != fv)
{
father[fu] = fv;
ans += w;
cnt++;
if (cnt == n - 1)
{
break;
}
}
}
cout << ans << endl;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int u, v, w;
cin >> u >> v >> w;
edges[i] = { u, v, w };
}
kruskal();
return 0;
}
```
3. Dijkstra算法求指定顶点到其他各顶点的最短路径
算法思路:从起点开始,每次选择一个距离起点最近的未确定最短路径的顶点,更新与其相邻的顶点的最短路径。
代码实现:
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
int n, m, start;
int graph[MAXN][MAXN]; //邻接矩阵存储图
int dist[MAXN]; //记录每个顶点与起点的最短距离
bool visited[MAXN]; //记录每个顶点是否已经确定最短路径
void dijkstra()
{
memset(dist, INF, sizeof(dist));
memset(visited, false, sizeof(visited));
dist[start] = 0; //将起点的距离设为0
for (int i = 0; i < n; i++)
{
int u = -1;
for (int j = 0; j < n; j++)
{
if (!visited[j] && (u == -1 || dist[j] < dist[u]))
{
u = j;
}
}
visited[u] = true;
for (int v = 0; v < n; v++)
{
if (!visited[v] && graph[u][v] != INF)
{
dist[v] = min(dist[v], dist[u] + graph[u][v]);
}
}
}
}
int main()
{
cin >> n >> m >> start;
memset(graph, INF, sizeof(graph));
for (int i = 0; i < m; i++)
{
int u, v, w;
cin >> u >> v >> w;
graph[u][v] = w;
}
dijkstra();
for (int i = 0; i < n; i++)
{
cout << dist[i] << " ";
}
cout << endl;
return 0;
}
```
4. 最短路径 D 算法的优化
最短路径 D 算法可以通过使用堆来优化,使得每次选取距离起点最近的未确定最短路径的顶点的时间复杂度从 $O(n)$ 优化到 $O(\log n)$。
代码实现:
```c++
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
int n, m, start;
int graph[MAXN][MAXN]; //邻接矩阵存储图
int dist[MAXN]; //记录每个顶点与起点的最短距离
bool visited[MAXN]; //记录每个顶点是否已经确定最短路径
void dijkstra()
{
memset(dist, INF, sizeof(dist));
memset(visited, false, sizeof(visited));
dist[start] = 0; //将起点的距离设为0
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push(make_pair(0, start));
while (!pq.empty())
{
int u = pq.top().second;
pq.pop();
if (visited[u])
{
continue;
}
visited[u] = true;
for (int v = 0; v < n; v++)
{
if (!visited[v] && graph[u][v] != INF && dist[v] > dist[u] + graph[u][v])
{
dist[v] = dist[u] + graph[u][v];
pq.push(make_pair(dist[v], v));
}
}
}
}
int main()
{
cin >> n >> m >> start;
memset(graph, INF, sizeof(graph));
for (int i = 0; i < m; i++)
{
int u, v, w;
cin >> u >> v >> w;
graph[u][v] = w;
}
dijkstra();
for (int i = 0; i < n; i++)
{
cout << dist[i] << " ";
}
cout << endl;
return 0;
}
```
以上就是根据图的抽象数据类型的定义使用邻接矩阵实现图的一些算法的代码实现。
阅读全文