CF938D Buy a Ticket 题解
题目大意
题目传送门
给定n个点,m条边,点权与边权告诉你,你要输出n个数,第i个数表示以i为起点,以任意一点为终点的最短路*2+终点点权中最少的一个
思路
我们知道起点,但终点不知道,而且有点权的阻碍,SPFA,dijkstra不能运用在有点权的图上,那只能用Floyd算法,但时间复杂度是O(n3);会超时
观察一下数据范围,差不多是O(nlog2n)的?那岂不是dijkstra的复杂度?我们可不可以把点权化为边权然后再dijkstra?
隆重介绍——虚拟源点
虚拟源点
既然要把点权化为边权,但边有起点和终点,不知道往哪里连,我们可以搞一个虚拟的起点用来连接,边权就是点权,这样终点变为虚拟源点,起点是任意一点,这不就好起来了?
细节
因为要来回,我们在存边的时候直接将边权*2再存进去,本来是以任意一点为起点,以虚拟源点为终点,我们可以反过来,以虚拟源点为起点,以所有点为终点即可使用dijkstra
dijkstra一定要堆优化或优先队列优化,否则会TLE
代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct Edge{
//边结构体
int v;
long long w;
};
struct Node{
//点结构体
int nodeId;
long long weight;
bool operator>(const Node &r) const{
return r.weight < weight;
}//重载运算符,就是以Weight为第一关键字进行排序
};
vector<Edge></