题目链接
最短路模板题。
相信各位大佬都会Dijkstra吧。
好吧,还是说一下。
Dijkstra 算法
由来
由荷兰计算机科学家 Edsger Wybe Dijkstra (狄克斯特拉)于1959 年提出。
特点
复杂度有保障,不怕被卡(有前提的)。
优点
时间复杂度是O(N^2)。
缺点
不能处理负边权。
思想
每次使用与起点已确定最短距离的顶点来更新后续顶点。
流程
a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。
b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
d.重复步骤b和c直到所有顶点都包含在S中。
证明
其实我也不会
本题就直接跑一遍最短路就可以了。但有一点细节。题上要求的是乘积最小。那么我们就不能直接跑。
其实我们可以跑一遍让路径上的边权log的和最小,这样就保证了乘积最小。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<queue>
#define N 2001001
#define re register
#define eps 1e-10
#define MAX 2001
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=9987;
inline void read(re ll &ret)
{