鱼C论坛

 找回密码
 立即注册
查看: 1568|回复: 7

有大佬有用数组模拟的dijkstra模板吗 是静态数组,不是动态的

[复制链接]
发表于 2023-10-7 22:48:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
有大佬有用数组模拟的dijkstra模板吗 是静态数组,不是动态的

自己想脑袋要炸了

用数组模拟邻接表的模板就是这个:

  1. #include <iostream>
  2. #include <cstring>

  3. using namespace std;

  4. const int N = 1005, M = 10005;

  5. int h[N], e[M], nex[M], idx = 0;

  6. void add(int a,int b)
  7. {
  8.         e[idx] = b;
  9.         nex[idx] = h[a];
  10.         h[a] = idx;
  11.         idx++;
  12.        
  13.        
  14. }


  15. int main()
  16. {
  17.         int n, m;
  18.         int a, b;
  19.         memset(h, -1, sizeof(h)); // 初始化
  20.        
  21.         cin >> n >> m; // 输入点数,边数
  22.         for (int i=1;i<=m;i++)
  23.         {
  24.                 cin >> a >> b;
  25.                 add(a, b);
  26.                 add(b, a);
  27.                
  28.         }
  29.        
  30.         for (int i=1;i<=n;i++)
  31.         {
  32.                 cout << i << "->";
  33.                 for (int j=h[i];j!=-1;j=nex[j])
  34.                 {
  35.                        
  36.                         cout << e[j] << "->";
  37.                 }
  38.                 cout << endl;
  39.         }
  40.        
  41.        
  42.        
  43.         return 0;
  44. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-10-7 22:49:06 | 显示全部楼层
以下是用静态数组模拟Dijkstra算法的模板代码,其中dist[ i]表示起点到i点的最短距离,vis[ i]表示i点是否已经取得最短距离:

  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;

  4. const int N = 1005;
  5. int g[N][N]; // 存储邻接矩阵
  6. int dist[N]; // 距离数组
  7. bool vis[N]; // 标记数组

  8. int n, m, s; // 点数、边数、起点编号

  9. void dijkstra()
  10. {
  11.     memset(dist, 0x3f, sizeof dist); // 初始化距离数组为无穷大
  12.     dist[s] = 0; // 起点到自身的距离为0

  13.     for (int i = 0; i < n; i++)
  14.     {
  15.         int t = -1; // 找到未取得最短距离的点中距离最小的点
  16.         for (int j = 1; j <= n; j++)
  17.             if (!vis[j] && (t == -1 || dist[t] > dist[j]))
  18.                 t = j;

  19.         vis[t] = true; // 标记该点已取得最短距离

  20.         // 更新未取得最短距离的点的距离
  21.         for (int j = 1; j <= n; j++)
  22.             dist[j] = min(dist[j], dist[t] + g[t][j]);
  23.     }
  24. }

  25. int main()
  26. {
  27.     cin >> n >> m >> s;

  28.     memset(g, 0x3f, sizeof g); // 初始化邻接矩阵为无穷大
  29.     while (m--)
  30.     {
  31.         int a, b, c;
  32.         cin >> a >> b >> c;
  33.         g[a][b] = min(g[a][b], c); // 处理重边和自环边
  34.         if (a != b) g[b][a] = min(g[b][a], c);
  35.     }

  36.     dijkstra();

  37.     for (int i = 1; i <= n; i++)
  38.         cout << dist[ i] << " ";

  39.     return 0;
  40. }
复制代码


需要注意的是,为了防止数组越界,在邻接矩阵g和dist数组的大小都要开到n+1。
请注意,本回答来自GPT-3.5
如果问题已经解决,请设置最佳答案
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-7 22:49:58 | 显示全部楼层
这是一个使用数组模拟邻接表的Dijkstra算法模板。它使用静态数组来存储图的边和邻接关系。

首先,我们定义了常量N和M来表示图中的点数和边数。然后,我们定义了一个数组h来存储每个点的邻接表的头指针。数组e和nex分别用于存储边的终点和下一条边的索引。变量idx用于表示当前边的索引。

接下来,我们定义了一个add函数,用于向邻接表中添加边。在add函数中,我们将边的终点存储在数组e中,将当前点的邻接表头指针存储在数组nex中,并更新当前点的邻接表头指针。

在主函数中,我们首先初始化邻接表头指针数组h为-1,表示每个点的邻接表为空。然后,我们输入点数n和边数m。接下来,我们使用一个循环来读取每条边的起点和终点,并调用add函数将边添加到邻接表中。

最后,我们使用两个嵌套循环来遍历每个点的邻接表,并输出每个点的邻接点。我们首先输出当前点的编号,然后遍历当前点的邻接表,输出每个邻接点的编号。每个邻接点之间用箭头->分隔,每个点的邻接表输出完毕后换行。

这个模板可以用来模拟有向图或无向图的邻接表,并且可以方便地进行Dijkstra算法等图算法的实现。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-7 22:50:15 | 显示全部楼层
以下是使用静态数组模拟的Dijkstra算法模板示例:
  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4. const int N = 1005;
  5. const int INF = 0x3f3f3f3f; // 表示无穷大
  6. int g[N][N]; // 存储图的邻接矩阵
  7. int dist[N]; // 存储源点到各个顶点的最短距离
  8. bool vis[N]; // 记录顶点是否已被访问
  9. void Dijkstra(int n, int s) {
  10.     memset(dist, INF, sizeof(dist)); // 初始化距离为无穷大
  11.     memset(vis, false, sizeof(vis)); // 初始化所有顶点未被访问
  12.     dist[s] = 0; // 源点到自身的距离为0
  13.     for (int i = 0; i < n; i++) {
  14.         int u = -1, minDist = INF; // u用于记录当前未访问顶点中距离最小的顶点
  15.         // 寻找距离最小的顶点
  16.         for (int j = 0; j < n; j++) {
  17.             if (!vis[j] && dist[j] < minDist) {
  18.                 u = j;
  19.                 minDist = dist[j];
  20.             }
  21.         }
  22.         if (u == -1) break; // 所有顶点都访问过,退出循环
  23.         vis[u] = true; // 标记顶点u为已访问
  24.         // 更新源点到其他未访问顶点的距离
  25.         for (int v = 0; v < n; v++) {
  26.             if (!vis[v] && g[u][v] != INF) {
  27.                 dist[v] = min(dist[v], dist[u] + g[u][v]);
  28.             }
  29.         }
  30.     }
  31. }
  32. int main() {
  33.     int n, m;
  34.     cin >> n >> m; // 输入点数n和边数m
  35.     // 初始化邻接矩阵,将除对角线外的元素初始化为无穷大
  36.     memset(g, INF, sizeof(g));
  37.     for (int i = 0; i < n; i++) g[i][i] = 0;
  38.     int a, b, c;
  39.     for (int i = 0; i < m; i++) {
  40.         cin >> a >> b >> c; // 输入边的起点、终点和权值
  41.         g[a][b] = min(g[a][b], c); // 若存在多条边,则取最小的权值
  42.     }
  43.     int s;
  44.     cin >> s; // 输入源点s
  45.     Dijkstra(n, s);
  46.     // 输出源点到各个顶点的最短距离
  47.     for (int i = 0; i < n; i++) {
  48.         cout << "源点" << s << "到达顶点" << i << "的最短距离为:" << dist[i] << endl;
  49.     }
  50.     return 0;
  51. }
复制代码

此模板使用静态数组来模拟Dijkstra算法,其中g数组存储图的邻接矩阵,dist数组存储源点到各个顶点的最短距离,vis数组记录顶点是否已被访问。算法的核心是通过遍历未访问的顶点,选择距离最小的顶点进行松弛操作,更新最短距离。

希望以上回答对你有帮助!如果还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-7 22:51:05 | 显示全部楼层
陶远航 发表于 2023-10-7 19:49
以下是用静态数组模拟Dijkstra算法的模板代码,其中dist[ i]表示起点到i点的最短距离,vis[ i]表示i点是否 ...

这是邻接矩阵啊@tommyyu @zhangjinxuan @学习编程中的Ben @额外减小
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-8 00:23:44 | 显示全部楼层
等我先学完基础的图论再来看。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-8 15:56:05 | 显示全部楼层
解一:你应该这么问,C语言写这个怎么写

解二:手写 vector
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-8 15:57:07 | 显示全部楼层
所以你要卡常吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 05:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表