P1001 A+B Problem(整活-dijstra堆优化)

        

题目描述

输入两个整数 a,b,输出它们的和(∣a∣,∣b∣≤109)。

注意

  1. Pascal 使用 integer 会爆掉哦!
  2. 有负数哦!
  3. C/C++ 的 main 函数必须是 int 类型,而且 C 最后要 return 0。这不仅对洛谷其他题目有效,而且也是 NOIP/CSP/NOI 比赛的要求!

好吧,同志们,我们就从这一题开始,向着大牛的路进发。

任何一个伟大的思想,都有一个微不足道的开始。

输入格式

两个以空格分开的整数。

输出格式

一个整数。

输入输出样例

输入 #1复制

20 30

输出 #1复制

50

-------------------------------------------------------------------------------------------------------------------OK啊,读完题了,正片开始

        这是一道十分淼的题目,乍一看,这不就是dijstra堆优化模板题吗?

        首先,建立三个节点,两条线,即:

               

        行,OK开始Code

        

#include <bits/stdc++.h>
using namespace std;
const long long N = 99999, M = 999999;
typedef pair<long long, long long> PII;
priority_queue<PII, vector<PII>, greater<PII> > q;
long long n, p, c, k, x, y, l;
long long pre[N];//链表头
long long d[N];//dis距离数组
bool f[N];//标记数组
struct Node {
	long long v, next, len;//链式前向星
} a[M * 2];
void add(long long u, long long v, long long len) {
	a[++k] = {v, pre[u], len};
	pre[u] = k;
}//建边
int dijkstra(long long h) {
	d[h] = 0;
	q.push({0, h});
	while (!q.empty()) {
		PII b = q.top();
		long long dis = b.first;
		long long pi = b.second;
		q.pop();
		if (f[pi]) continue;
		f[pi] = true;
		for (long long i = pre[pi]; i; i = a[i].next) {
			long long to = a[i].v;
			if (d[to] > dis + a[i].len) {
				d[to] = dis + a[i].len;
				q.push({d[to], to});
			}
		}
	}
	return d[3];
}//dijstra堆优化
int main() {
	//全开longlong防止数据爆掉
	cin >> x >> y; //读入x,y;
	//使用链式前向星进行建图
	add(1, 2, x);
	add(2, 3, y);
	memset(d, 0x3f, sizeof(d));
	memset(f, 0, sizeof(f));
	cout << dijkstra(1); //开始跑dijstra堆优化
	return 0;
}

 时间复杂度
 总共需要遍历 2 条边,插入数据修改小根堆的时间复杂度为  O(N log N)所以时间复杂度为 O(3*log3)。因为对于 稀疏图 来说边数与点数很接近,所以可以看做为 O(n*logn)。但是对于 稠密图 来说边数接近点数的平方个,如果稠密图使用堆优化版的Dijkstra算法,那么时间复杂度将会是 O(n^2*logn),显然不如直接使用朴素Dijkstra算法。所以 堆优化版的Dijkstra算法 更适用于 稀疏图 ,而 朴素Dijkstra算法 更适用于 稠密图。

        综上所述:本程序的时间复杂度为O(3*log3)

        最后祝大家早日成为大牛

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值