POJ-图论-最短路模板(邻接矩阵)
2024-08-31 14:59:20
POJ-图论-最短路模板
一、Floyd算法
刚读入数据时,G为读入的图邻接矩阵,更新后,G[i][j]表示结点i到结点j的最短路径长度
int G[N][N];//二维数组,其初始值即为该图的邻接矩阵
1.init():初始化图邻接矩阵
void init()
{
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
G[i][j] = -;//初始化邻接矩阵,用-1代表无穷
}
G[i][i] = ;//初始化,自己到自己的路径长度为0
}
}
2.floyd():更新最短路径
void floyd()
{
for (int k = ; k <= n; k++)//从1至n循环k
{
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)//遍历所有的i,j
{
if (G[i][k] == -1 || G[k][j] == -1)continue;
if (G[i][j] == -1 || G[i][k] + G[k][j] < G[i][j])G[i][j] = G[i][k] + G[k][j];
}
}
}
}
例 5.5 最短路
模板代码
#include<cstdio>
const int N = ;
int G[N][N];
int n, m; void init()
{
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
G[i][j] = -;//初始化为无穷
}
}
for (int i = ; i <= n; i++)G[i][i] = ;//自己到自己距离是0
} void floyd()
{
for (int k = ; k <= n; k++)
{
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
if (G[i][k] == - || G[k][j] == -)continue;
else if (G[i][j] == - || G[i][j] > G[i][k] + G[k][j])G[i][j] = G[i][k] + G[k][j];
}
}
}
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
if (n == && m == )break;
init();
int x, y, t;
for (int i = ; i < m; i++)
{
scanf("%d%d%d", &x, &y, &t);
G[x][y] = G[y][x] = t;
}
floyd();
printf("%d\n", G[][n]);
}
return ;
}
二、Dijkstra算法
G为图邻接矩阵,G[i][j]表示读入的i到j的距离,后面不再更新。d[]为距离数组,d[i]表示结点i到起点的最短距离。vis[N]为访问数组,记录各结点的访问情况。
int G[N][N]; // 图邻接矩阵
int d[N]; // 表示起点到各结点的最短距离
bool vis[N] = { false }; // 表示各结点被访问过与否
1.init():初始化邻接矩阵,到自身的距离为0
void init() // 初始化
{
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
if (i == j) G[i][j] = ;
else G[i][j] = INF;
}
}
}
2.Dijkstra(int start):初始化d[]之后,进行n次循环,每次先确定与起点直接相连的距离最小结点u及其距离d[u],再更新起点到其他结点v的距离d[v]。
void Dijkstra(int start)
{
for (int i = ; i <= n; i++) d[i] = INF;//可达距离都初始化为无穷
d[start] = ; // 起初只有start结点可达
for (int i = ; i <= n; i++)
{
int u = -; // 距离最近的结点u,初始化为-1
int min = INF; // min存放最小的d[u],初始化为无穷
for (int j = ; j <= n; j++)//得到最近的点
{
if (vis[j] == false && d[j] < min)
{
u = j; // 与起点直接相连的距离最小结点
min = d[j];
}
}
if (u == -) return; // 说明剩下的未被访问过的结点都是与起点不可达的
vis[u] = true; // 设为已读
for (int v = ; v <= n; v++)//由新得到的点更新后面所有点
{
// 此处d[u]有一个相加操作,所以在设置很大整数时不能设置为0x7fffffff,会导致溢出
if (vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]) d[v] = d[u] + G[u][v];
}
}
}
例 5.5 最短路
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = ;
const int INF = 0x3fffffff;
int n, m;
int G[N][N];
int d[N];//起点到各点的距离
bool vis[N] = { false }; void init()
{
for (int i = ; i <= n; i++)
{
for (int j = ; j <= n; j++)
{
G[i][j] = INF;
}
G[i][i] = ;
}
for (int i = ; i <= n; i++)
{
d[i] = INF;
vis[i] = false;
}
} void djkstra(int start)
{
d[start] = ;
for (int i = ; i <= n; i++)//每次加入一个结点(这时连起点都还没加入)
{
int u = -;//最近的结点
int min = INF;//最近的距离值
for (int j = ; j <= n; j++)
{
if (vis[j] == false && d[j] < min)
{
min = d[j];
u = j;
}
}
if (u == -)return;//无路可走
vis[u] = true;
for (int v = ; v <= n; v++)//更新其他节点
{
if (vis[v] == false && G[u][v] != INF && d[v] > d[u] + G[u][v])d[v] = d[u] + G[u][v];
}
}
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
if (n == && m == )break;
init();
for (int i = ; i < m; i++)
{
int a, b, t;
scanf("%d%d%d", &a, &b, &t);
G[a][b] = G[b][a] = t;
}
djkstra();
printf("%d\n", d[n]);
}
return ;
}
最新文章
- Redis【知识点】批量删除指定Key
- bash 语法使用
- Switch语句的case穿透
- centos6.5 64bit 实现root开机自动登录X桌面
- 层叠样式表(CSS)
- Performance plugin离线安装
- swiper 页面双向设置
- Windows Phone性能优化建议
- 《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记
- Android App 性能评测与调优
- 使用jni技术进行android应用签名信息核查及敏感信息保护
- tmp1
- 词云(wordcloud2.js js2wordcloud.js)
- Ansi与Unicode编码
- printf的执行顺序
- [development][C][thread_local] 线程全局变量
- Linxu
- iis下的php环境的配置
- C# 获取textbox行数
- Maven 学习笔记(一) 基础环境搭建
热门文章
- Nested List Weight Sum
- python Image open读取网络图片本地显示 爬虫必备
- 20181107 模拟赛T1:快乐传递政治正确版
- JVM相关内容简介(转)
- 了解Vuex状态管理模式的理解强化指南
- DNN的BP算法Python简单实现
- vue-skeleton-webpack-plugin骨架屏与page-skeleton-webpack-plugin骨架屏生成插件
- svn报错:[Previous operation has not finished; run &#39;cleanup&#39; if it was interrupted] 的排错过程
- python 整数转16进制数
- linux 去掉 ^M 的方法