*对最短路径问题以及floyd算法、Dijkstra算法不是很理解的同学请移步前几篇博客~

题目链接:

http://lx.lanqiao.cn/problem.page?gpid=T15

问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

解题思路:

我们看到,这是一个有负值的有向图最短路径问题,我们直到,含有负值的边我们是无法使用Dijkstra的,原因很简单,Dijkstra是采用贪心的思想

其目光比较短浅23333,Dijkstra是不会想到 如果A→B大于A→C 但是还存在一个点K,使A→B→K→C要小于AC这样的情况的

所以我们先采取全部枚举的floyd算法处理一下这道题

#include<stdio.h>
#define INF 0xFFFFFFF
int a[8010][8010];
int fmin(int a,int b)
{return a<b?a:b;
}
int main()
{int n,m,i,j,k;int u,v,l;while(~scanf("%d%d",&n,&m)){for(i=1;i<=n;i++)for(j=1;j<=n;j++)i==j?a[i][j]=0:a[i][j]=INF;while(m--){scanf("%d%d%d",&u,&v,&l);a[u][v]=fmin(a[u][v],l);}for(k=1;k<=n;k++)         //存在一个k 使aik+akj路径小于aij for(i=1;i<=n;i++) for(j=1;j<=n;j++)          a[i][j]=fmin(a[i][j],a[i][k]+a[k][j]);  for(i=2;i<=n;i++)printf("%d\n",a[1][i]);}return 0;
}

显然是不行的啦=.=

然后我们可以尝试一些优化的方法:

我们把无效路径压缩一下:思路可以参考http://blog.csdn.net/sm9sun/article/details/53258503

#include<stdio.h>
#define inf 0xFFFFFFF
int dp[20011][1600][2]; //对于i点j条边所对应的点以及权值
int count[20011];       //i点总共的边数
int o[20011];           //optimum
int fmin(int a,int b)
{return a<b?a:b;
}
void sx(int k)
{    int i;for(i=0;i<count[k];i++) {if((o[dp[k][i][0]])>(o[k]+dp[k][i][1])){o[dp[k][i][0]]=o[k]+dp[k][i][1];sx(dp[k][i][0]);}}
}
int main()
{
int i,j,k,n,m;
int s,e,l;
while(~scanf("%d%d",&n,&m))
{for(i=1;i<=n;i++){count[i]=0;o[i]=inf;}for(i=1;i<=m;i++){scanf("%d%d%d",&s,&e,&l);dp[s][count[s]][0]=e;dp[s][count[s]][1]=l;count[s]++;}for(i=0;i<count[1];i++)o[dp[1][i][0]]=fmin(o[dp[1][i][0]],dp[1][i][1]);for(k=2;k<=n;k++)         //存在一个k 使aik+akj路径小于aij sx(k);for(i=2;i<=n;i++)printf("%d\n",o[i]);}
return 0;
}

最后两个数据还是无法过~我们再优化一下输入

#include<stdio.h>
#define inf 0xFFFFFFF
int dp[20011][1600][2];
int count[20011];
int o[20011];
int fmin(int a,int b)
{return a<b?a:b;
}
void sx(int k)
{    int i;for(i=0;i<count[k];i++) {if((o[dp[k][i][0]])>(o[k]+dp[k][i][1])){o[dp[k][i][0]]=o[k]+dp[k][i][1];sx(dp[k][i][0]);}}
}
void dr()
{int s,e,l,j;scanf("%d%d%d",&s,&e,&l);for(j=0;j<count[s];j++){if(dp[s][j][0]==e){dp[s][j][1]=fmin(dp[s][j][1],l);return;}}   dp[s][count[s]][0]=e;dp[s][count[s]][1]=l;count[s]++;}int main()
{
int i,j,k,n,m;while(~scanf("%d%d",&n,&m))
{   for(i=1;i<=n;i++){count[i]=0;o[i]=inf;}for(i=1;i<=m;i++)dr();for(i=0;i<count[1];i++)o[dp[1][i][0]]=fmin(o[dp[1][i][0]],dp[1][i][1]);for(k=2;k<=n;k++)         //存在一个k 使aik+akj路径小于aij sx(k);for(i=2;i<=n;i++)printf("%d\n",o[i]);
}
return 0;
}

后面的数据的确有了提升,但是依然不满足最后的数据~

那么对于含有负权值的最短路径问题我们该如何处理呢?请看下一篇博客——SPFA算法

最短路径——Floyd算法及优化(蓝桥杯试题集)相关推荐

  1. 最短路径——SPFA算法(蓝桥杯试题集)

    *对于本题的floyd题解请跳转:http://blog.csdn.net/sm9sun/article/details/53285870 题目链接: http://lx.lanqiao.cn/pro ...

  2. java蓝桥杯的题_Java蓝桥杯试题集——算法训练ALGO-116——最大的算式

    题目要求 解题思路 动态规划,今天才弄明白QAQ,借鉴了这位大佬的博客,曹磊的博客 写的很好!但是我觉得我的循环方式更容易理解嘿嘿嘿~ 首先建立如下图的数组,行数代表前几位数,列数代表有几个乘号.将第 ...

  3. 线段树——操作格子(蓝桥杯试题集)

    题目链接: http://lx.lanqiao.cn/problem.page?gpid=T18 题目描述: 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个 ...

  4. 最小生成树——安慰奶牛(蓝桥杯试题集)

    *对prim算法.Kruskal算法不是很理解的请移步 http://blog.csdn.net/sm9sun/article/details/53256232  //并查集 http://blog. ...

  5. 动态规划——K号数(蓝桥杯试题集)

    题目链接:http://lx.lanqiao.cn/problem.page?gpid=T13 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求 ...

  6. 动态规划——节点选择(蓝桥杯试题集)

    题目链接: http://lx.lanqiao.cn/problem.page?gpid=T14 问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相 ...

  7. 动态规划——看似dp的贪心问题最大乘积(蓝桥杯试题集)

    题目链接: http://lx.lanqiao.cn/problem.page?gpid=T136 问题描述 对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢? 输入格式 第一行一个数表示数 ...

  8. 蓝桥杯研究生c语言试题答案,蓝桥杯试题_蓝桥杯 你有蓝桥杯历年的试题吗最好有参考答案啊 高职高专组C语言的 有的话麻烦你发给我 万分感谢_淘题吧...

    ❶ 蓝桥杯 你有蓝桥杯历年的试题吗最好有参考答案啊. 高职高专组C语言的 有的话麻烦你发给我 万分感谢 我有真题.但是老师没给答案 ❷ 为什么蓝桥杯试题集评测老是错 楼上的网友说的很简单,实际上因为每 ...

  9. 蓝桥杯 试题 算法训练 无聊的逗 C++ 详解

    题目: 逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中.不过他想到了一个游戏来使他更无聊.他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的 ...

最新文章

  1. 全球及中国箱包市场需求前景与投资动态分析报告2022版
  2. my batis的理解
  3. 给opentaps添加定制的表和字段
  4. 通过避免下列 10 个常见 ASP.NET 缺陷使网站平稳运行(转)
  5. 选择自己用的到的文件编译一个CEGUISample(一)
  6. XML序列之System.Xml.Serialization
  7. 【小白冲冲冲!!!】37. ORBSLAM初始化时为什么要同时初始化H矩阵和F矩阵?
  8. 大型项目编译注意事项
  9. php如何获取li标签中的值,多个 (li) 标签如何获取获取选中的里面的某个特定值??...
  10. 【定位问题】基于matlab GUI RSSI无线定位【含Matlab源码 1054期】
  11. mac 二进制安装mysql_教程方法;在mac下安装mysql二进制分发版的方法(不是dmg的)电脑技巧-琪琪词资源网...
  12. 搜狗词库scel格式转txt文本
  13. iOS UI自动化测试详解
  14. 关于工业大数据,这是最完整的介绍了,附60页PPT
  15. 面试题-实现数组map方法
  16. kubectl命令的使用、滚动更新以及回滚操作
  17. python语言应用 智慧树满分章节测试答案_Python语言应用完整智慧树网课章节测试答案...
  18. 嵌入式linux内核移植
  19. python读json文件json.decoder.JSONDecodeError终极解决大法
  20. mysql 红黑树_微信大牛教你深入了解数据库索引

热门文章

  1. 3 MM配置-企业结构-定义-定义库存地点
  2. ftp响应码以及解释说明是服务器返回,FTP命令字和响应码解释
  3. html css div显示隐藏,Html-Css-div透明层剧中
  4. java yeild_Java 中 Thread.yield() 方法详解
  5. 蓝牙扫描_无线扫描枪常见的传输模式及其区别
  6. ps中如何同图层获取css代码
  7. Creative主题电子科技企业类discuz模板
  8. 百度SEO emlog博客lu1.3模板
  9. HTML5汽车轮毂改装网站模板
  10. java导入项目存在,如何将预先存在的Java项目导入Eclipse并启动并运行?