c++定义一有n个结点的的以邻接矩阵为存储方式的网(有向),并对其进行如下操作: 1.深度优先遍历,并输出遍历序列; 2.广度优先遍历,并输出遍历序列; 3.求源点到图中每个点的最短路径,并输出;
时间: 2024-03-25 19:42:04 浏览: 72
好的,我来解答你的问题。
首先,我们需要用邻接矩阵来表示这个有向网。假设这个有向网有 $n$ 个节点,那么我们可以用一个 $n \times n$ 的矩阵 $G$ 来表示它,其中 $G[i][j]$ 表示从节点 $i$ 到节点 $j$ 的边的权值。如果节点 $i$ 和节点 $j$ 之间没有边相连,则 $G[i][j]$ 取一个很大的数(比如 $INF=999999$)表示它们之间没有路径。
下面是使用邻接矩阵存储有向网的 C++ 代码:
```cpp
const int MAXN = 1005; // 最大节点数
const int INF = 999999; // 表示两个节点之间没有边相连
int n; // 节点数
int G[MAXN][MAXN]; // 邻接矩阵
// 输入邻接矩阵
void input() {
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> G[i][j];
if (G[i][j] == -1) G[i][j] = INF;
}
}
}
```
接下来,我们分别介绍深度优先遍历、广度优先遍历和最短路径算法的实现。
1. 深度优先遍历
深度优先遍历是一种递归算法。从某个节点开始遍历,先访问它的邻居节点,然后再递归访问邻居节点的邻居节点,直到遍历完整个图。
下面是使用深度优先遍历遍历整个图的 C++ 代码:
```cpp
bool vis[MAXN]; // 标记节点是否被访问过
// 深度优先遍历
void dfs(int u) {
vis[u] = true; // 标记节点 u 已经被访问过
cout << u << " "; // 输出遍历序列
for (int v = 1; v <= n; v++) {
if (G[u][v] < INF && !vis[v]) {
dfs(v);
}
}
}
// 遍历整个图
void dfs_traverse() {
memset(vis, false, sizeof(vis));
for (int u = 1; u <= n; u++) {
if (!vis[u]) {
dfs(u);
}
}
}
```
2. 广度优先遍历
广度优先遍历是一种非递归算法。从某个节点开始遍历,先访问它的邻居节点,然后将邻居节点加入队列,再依次访问队列中的节点,直到队列为空。
下面是使用广度优先遍历遍历整个图的 C++ 代码:
```cpp
bool vis[MAXN]; // 标记节点是否被访问过
// 广度优先遍历
void bfs(int u) {
queue<int> q;
q.push(u);
vis[u] = true; // 标记节点 u 已经被访问过
while (!q.empty()) {
int v = q.front(); q.pop();
cout << v << " "; // 输出遍历序列
for (int w = 1; w <= n; w++) {
if (G[v][w] < INF && !vis[w]) {
q.push(w);
vis[w] = true; // 标记节点 w 已经被访问过
}
}
}
}
// 遍历整个图
void bfs_traverse() {
memset(vis, false, sizeof(vis));
for (int u = 1; u <= n; u++) {
if (!vis[u]) {
bfs(u);
}
}
}
```
3. 最短路径算法
最短路径算法可以求出从源点到图中每个点的最短路径。这里介绍一种经典的算法——Dijkstra 算法。
Dijkstra 算法的基本思想是:维护一个集合 $S$,表示已经求出最短路径的节点的集合,和一个数组 $dis$,表示源点到各个节点的最短距离。每次从集合 $V-S$ 中选择距离源点最近的节点 $u$,并将其加入集合 $S$ 中,然后更新与节点 $u$ 相邻的节点 $v$ 的最短距离 $dis[v]$。这样,当所有节点都被加入集合 $S$ 中时,$dis[i]$ 就表示源点到节点 $i$ 的最短距离。
下面是使用 Dijkstra 算法求源点到图中每个点的最短路径的 C++ 代码:
```cpp
int dis[MAXN]; // 存储源点到各个节点的最短距离
bool vis[MAXN]; // 标记节点是否已经加入集合 S 中
// Dijkstra 算法
void dijkstra(int s) {
memset(vis, false, sizeof(vis));
memset(dis, 0x3f, sizeof(dis)); // 初始化 dis 数组为一个很大的数
dis[s] = 0; // 源点到自己的距离为 0
for (int i = 1; i <= n; i++) {
int u = -1;
for (int j = 1; j <= n; j++) { // 选择距离源点最近的节点 u
if (!vis[j] && (u == -1 || dis[j] < dis[u])) {
u = j;
}
}
vis[u] = true; // 将节点 u 加入集合 S 中
for (int v = 1; v <= n; v++) { // 更新节点 u 的邻居节点 v 的最短距离
if (G[u][v] < INF && dis[v] > dis[u] + G[u][v]) {
dis[v] = dis[u] + G[u][v];
}
}
}
}
// 输出源点到图中每个点的最短路径
void print_shortest_path(int s) {
for (int i = 1; i <= n; i++) {
cout << "源点 " << s << " 到节点 " << i << " 的最短路径为:" << dis[i] << endl;
}
}
```
最后,我们可以将上述三个算法整合在一起,完成题目所要求的操作:
```cpp
int main() {
input(); // 输入邻接矩阵
dfs_traverse(); // 深度优先遍历
cout << endl;
bfs_traverse(); // 广度优先遍历
cout << endl;
dijkstra(1); // 求源点到每个点的最短路径
print_shortest_path(1); // 输出源点到每个点的最短路径
return 0;
}
```
阅读全文