02 | 最短路径
最短路径
Floyed算法
解决的问题
- 求解任意两点之间的最短路径
- 可以处理带有负权边的图, 但不能处理带有“负环”的图
思想
对于要求解的两个点,我们给定任意一个点作为中间点,经过中间点的路径有没有可能比直接到达更短?
动态规划的思想
时间复杂度
一个小例子
#include <cstdio> #include <iostream> #include <cmath> #include <cstring> using namespace std; int a[101][3]; double f[101][101]; int n, i, j, k, x, y, m, s, e; int main() { freopen("short.in", "r", stdin); //重定向 freopen("short.out", "w", stdout); //重定向 cin >> n; //一共有n个点 for (i = 1; i <= n; ++i) { cin >> a[i][1] >> a[i][2]; //记录点的坐标 } cin >> m; //边的个数 memset(f, 0x7f, sizeof(f)); //初始化图,double两个字节 for (i = 1; i <= m; i++) { cin >> x >> y; f[y][x] = f[x][y] = sqrt(pow(double(a[x][1] - a[y][1]), 2) + pow(double(a[x][2] - a[y][2]), 2)); } cin >> s >> e; for (k = 1; k <= n; k++) { //加入中间点后的更新 for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if (i != j && i != k && j != k && f[i][k] + f[k][j] < f[i][j]) f[i][j] = f[i][k] + f[k][j]; } printf("%.2lf\n", f[s][e]); return 0; }
输出结果
3.41
dijkstra算法
解决的问题
确定一点到其他任意点的路径最小值
思想
每次仅选一个最小的待确定的点为下一个确定点,并将这个变化更新。
贪心 + DP
一个小例子
#include <cstdio> #include <cstring> #define INF 0x3F3F3F3F //我们建立一个伪最大值,这个是由memset函数特性决定的 using namespace std; const int M = 1e4 + 10; const int N = 1000 + 10; int n, m, s; int mp[M][N]; //图的临界矩阵 int dis[N]; //dis为距离 bool vis[N]; //vis为待确定点(假设未确定点为蓝点,已确认的为白点) void dijkstra(int s) //求源点s到其他点的最短路径 { memset(vis, 0, sizeof(vis)); //0表示蓝点(未确定最短路径的点),1表示白点(确定路径的点) memset(dis, INF, sizeof(dis));//默认距离为无穷大 dis[s] = 0; //它自身的距离为0 while (1) { int mini = 0, min_ = INF; for (int j = 1; j <= n; j++) { if (!vis[j] && min_ > dis[j]) //从蓝点中找出最小的值 { mini = j; min_ = dis[j]; } } //如果没有蓝点,说明结束 if (mini == 0) break; //神来之笔,冒泡算法同样用到了 //如果确定下来一个最小的蓝点 vis[mini] = 1; //那么我们看一看加进来的这个白点对蓝点的影响 for (int i = 1; i <= n; i++) { if (vis[i]==0 && dis[i] > dis[mini] + mp[mini][i]) dis[i] = dis[mini] + mp[mini][i]; } } } int main() { memset(mp, INF, sizeof(mp)/4); while (scanf("%d%d", &n, &m) != EOF && n) { //注意这里可以一直测试下去 memset(mp, INF, sizeof(mp)); for (int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); mp[u][v] = mp[v][u] = w; //图是无权图 } dijkstra(1); // printf("%d\n", dis[n]); //输出源点1到目标点n的最短路径 } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)