题目描述:

样例:

实现解释:

所有结点对最短路径的板子题

知识点:

寻找所有结点对最短路径,动态规划

坑点:

无坑,注意建边即可

使用的算法为floyd算法

按照程序顺序解释如下:

首先建图,以邻接矩阵形式,初始化矩阵内容:对i==j的设为权值0,其他的设为INF(正无穷的大小取决于题目),以便后续计算时能区分自身和不可达结点。然后依据输入按照edge[u][v] = w的形式连点即可。

运行floyd算法

动态规划思想展现:最优子结构,状态转移方程

以下图为例:(来源网络)

上图中1号到5号的最短路径序列<1,2,4,5>,其子序列<1,2,4>也是最短路径。以dp[k][i][j]表示以点1到k之间的点为媒介时,从i到j的最短路径。那么为了进行状态转移,需要和之前的dp建立关系,则对dp[k-1][i][j]可有以下的两种情况:

  1.dp[k][i][j]的最短路不经过k

  dp[k][i][j]=dp[k-1][i][j]

  2.dp[k][i][j]的最短路经过k

  dp[k][i][j]=dp[k-1][i][k]+dp[k-1][k][j]

则有状态转移方程

dp[k][i][j] = min(dp[k-1][i][j], dp[k-1][i][k]+dp[k-1][k][j])(k,i,j∈[1,n])

边界条件即dp[0][i][j] = edge[i][j]

又从状态转移方程可看出,k只和k-1有关,因此可进行维度优化:

  dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j])(k,i,j∈[1,n])每次只需自身和另一种情况对比便可达到同样的效果。

  则从分析可知,程序内容其实和矩阵链乘十分类似,初始化dp数组(dp[i][j]=edge[i][j],边界条件)后,三层循环便可得到结果。

  具体可见代码。

完整代码:

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
#define MAX 210
#define INF 99999
int n,e;
int edges[MAX][MAX];
long long dp[MAX][MAX];
int path[MAX][MAX];
void createGraph()
{
int u,v,w;
cin >> n >> e;
for(int i = ; i<n; i++)
{
for(int j = ; j<n; j++)
{
if(i == j) edges[i][j] = ;
else edges[i][j] = INF;
}
}
for(int i = ; i<e; i++)
{
cin >> u >> v >> w;
edges[u-][v-] = w;
}
}
void getPath()
{
int from,to,length = -;
for(int i = ;i<n;i++)
{
for(int j = ;j<n;j++)
{
if(dp[i][j] != INF)
{
if(dp[i][j]>length)
{
from = i+;
to = j+;
length = dp[i][j];
}
}
}
}
cout << from << ' ' << to << '\n';
} void floyd()
{
for(int i = ;i<n;i++)
{
for(int j = ;j<n;j++)
{
dp[i][j] = edges[i][j];
}
}
for(int k = ;k<n;k++)
{
for(int i = ;i<n;i++)
{
for(int j = ;j<n;j++)
{
//抛去维度,直接计算
if(dp[i][j] > dp[i][k]+dp[k][j])
{
dp[i][j] = dp[i][k]+dp[k][j];
path[i][j] = k;
}
}
}
}
getPath();
}
int main()
{
int t;
cin >> t;
while(t--)
{
createGraph();
floyd();
}
return ;
}

最新文章

  1. log4net 记录MVC监控日志
  2. 如何通过cmd检查自己电脑是否安装了oracle
  3. cp命令
  4. Oracle中的NVL函数
  5. STM32先设置寄存器还是先使能时钟
  6. Common Linux log files name and usage--reference
  7. 【大数比较】NYOJ-73
  8. php如何判断是否为json数据(格式)
  9. Eclipse中的TreeViewer类和ListViewer类
  10. JFrame编程
  11. libgdx, mouse 关节
  12. linux 私房菜 CH8 linux 磁盘与文件系统管理
  13. RunTime 给类添加属性
  14. springboot+mybatis+thymeleaf项目搭建及前后端交互
  15. python 之模块random
  16. Python记录11:叠加多个装饰器+有参装饰器
  17. git的简单命令
  18. 从零开始学 Web 之 ES6(三)ES6基础语法一
  19. github链接与心得体会
  20. hive vs hbase

热门文章

  1. 免费 IP 代理池示例
  2. 2、react-生命周期1※※※
  3. kernel list 实践
  4. IP地址和端口
  5. Android学习笔记.9.png格式图片
  6. 商城05——首页轮播图显示实现&amp;Redis环境搭建&amp;Redis实现缓存
  7. phpmyadmin通过慢查询日志getshell连载(二)
  8. C# 什么是泛型 ?以及对泛型各方面的一些知识点的整理
  9. WeChair项目Alpha冲刺(2/10)
  10. 【面试篇】寒冬求职之你必须要懂的Web安全