IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 蓝桥杯 最短路问题 dijkstra算法负权值计算 -> 正文阅读

[数据结构与算法]蓝桥杯 最短路问题 dijkstra算法负权值计算

原题如下:
试题 算法训练 最短路

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给定一个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,保证从任意顶点都能到达其他所有顶点。

思路分析

很多人看到这题之后认为不能使用dijstra算法,原因是题目中包含负权值,但其实这题也是可以使用dijistra算法的,因为题目中已经说明了,不包含负环,其实就是一个隐含条件,暗示我们可以使用dijkstra算法。

首先,简单介绍一下dijkstra算法不能计算负环的原因。
dijkstra算法本身是基于贪心算法的逻辑,每一次都基于现有路径条件计算到某一起点的最短值。但是负权值一旦出现,算法逻辑就不再成立了。

因为目的是得到最短路径,而在负环中,最短路径是负无穷大,从我们的常规认识上来说就已经出现了问题。

当然从算法角度上来说,真正的问题是,因为负环的出现,导致算法不能保证每一步找到的路径就是当前节点的最短路径,贪心算法的查找也就失去了意义。

所以这题,从条件上看好像可以使用djikstra算法。

但是,需要考虑到的是,djikstra的时间复杂度为(N^2),而节点的数量可以达到20000个。也就是说超时的可能性非常大,实际运行中也证实了我的猜想。

两个节点为20000的数据没能通过……

但是,你以为我在这里就结束了嘛?不?我不能止步于此。

我尝试性的小小删改了djikstra的贪心查找部分,结果很轻易的拿到了满分,这是我没想到的。因为从逻辑上来说,如果不基于贪心来查找的话,对付复杂的环状图是容易出现问题的。因为节点的确定的最短路径可能一直变化(贪心查找时确定之后是不变的)。

原因分析:可能是测试数据用的图不参杂环状图,或者是简单的环状图

下面是修改后的代码:

 #include <iostream>
#include <stdio.h>
using namespace std;

int n, m,ma;

class l
{
public:
	int v, d;
	l *next;
	void init (int a=-1, int b=0)
	{
		v = a;
		d = b;
		next = NULL;
	}
};
l map [20005];
l* p;

class vertex
{
public:
	int b;
	int d;
	vertex(int a=200000)
	{
		b = 0;
		d = a;
	}
};
vertex v[20005];

void shortestroute()
{
	for (int i = 1; i < n; i++)
	{
		p = &map[0];
		while (p != NULL)
		{
			if (p->v ==i)
			{
				v[i].d = p->d;
			}
			p = p->next;
		}
	}
	ma = 200000;
	for (int i = 1; i < n;)
	{
		for (int j = 1; j < n; j++)
		{
			if (v[j].b == 0 && v[j].d < ma)
			{
				i+=1;

				v[j].b = 1;
				p = &map[j];
				while (p != NULL)
				{
					if (p->d + v[j].d < v[p->v].d)
					{
						v[p->v].d = p->d + v[j].d;
					}
					p = p->next;
				}
			}
		}
	}
	for (int i = 1; i < n; i++)
	{	
			cout << v[i].d<<endl;
	}
}

int main()
{
	int a,b,c;
	cin >> n >> m;

	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		if(map[a-1].d==0)
			map[a-1].init(b-1, c);
		else
		{
			p = new l;
			p->init(b-1, c);
			p->next = map[a-1].next;
			map[a-1].next = p;
		}
	}

	shortestroute();

	return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 16:16:15  更:2021-07-25 16:16:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 22:21:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码