[AHOI2002] 哈利·波特与魔法石
- 哈利·波特与魔法石
- 题目描述
- 输入格式
- 输出格式
- 样例
- 样例输入
- 样例输出
- 解题思路
- AC 代码
哈利·波特与魔法石
题目描述
输入格式
文件中第一行有七个数,分别是 S1、 S2 、 …、 S7 ;第二行有两个数,依次分别是起点城市 i 和终点城市 j ;第三行有一个正整数 c ,c<=10000, 表示随后的 c 行中每行存放了一对能直接通达的城市的信息。 能直接通达的城市的信息由三个数组成, 依次分别是两个城市的编号和这两个城市之间的地形。城市的编号都是不超过 100 的正整
数, 但是各个城市的编号未必连续。 文件里同一行中相邻的两个数都是用一个空白字符隔开的。
输出格式
以一行的形式输出起点城市i 与终点城市 j 之间的最快路线所需要的时间。
样例
样例输入
0 1 0 0 0 0 0
1 4
4
1 2 1
1 3 1
2 4 2
3 4 3
样例输出
5
解题思路
读地后发现,此题只是一个简单的最短路,使用迪克斯特拉算法即可简单解决:
迪杰斯特拉算法是一种用于解决单源最短路径问题的经典算法。它由荷兰计算机科学家艾兹赫尔·迪杰斯特拉于 1956 1956 1956年提出,被广泛应用于网络路由、交通规划、电信网络等领域。
该算法的目标是找到从给定源节点到所有其他节点的最短路径。它通过逐步扩展路径的方式来实现这一目标。算法的基本思想是,从源节点开始,逐步选择当前路径上最短的节点,并更新与该节点相邻的节点的距离。通过不断迭代,最终得到从源节点到所有其他节点的最短路径。
具体来说,迪杰斯特拉算法包含以下步骤:
-
初始化:将源节点的距离设置为 0 0 0,将所有其他节点的距离设置为无穷大。
-
选择当前路径上距离最短的节点,并标记该节点为已访问。
-
更新距离:对于当前节点的所有邻居节点,计算通过当前节点到达邻居节点的距离,并与邻居节点的当前距离进行比较。如果通过当前节点到达邻居节点的距离更短,则更新邻居节点的距离。
-
重复步骤 2 2 2和步骤 3 3 3,直到所有节点都被访问过或者没有可达节点为止。
最终得到从源节点到所有其他节点的最短路径。
迪杰斯特拉算法的时间复杂度为 O ( V 2 ) O(V^2) O(V2),其中V表示节点的数量。然而,通过使用优先队列等数据结构,可以将时间复杂度优化到 O ( ( V + E ) l o g V ) O((V+E)logV) O((V+E)logV),其中E表示边的数量。
迪杰斯特拉算法的优点是能够处理带有非负权重的图,并且对于稠密图效果较好。然而,该算法无法处理带有负权重的图,且在处理稀疏图时可能效率较低。
总之,迪杰斯特拉算法是一种经典的用于解决单源最短路径问题的算法,通过逐步扩展路径并更新节点的距离,找到从源节点到所有其他节点的最短路径。它在网络路由、交通规划等领域有着广泛的应用。
AC 代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[300][300],d[300],v[300],h[10]={0,2,6,4,8,6,10,14},s,t,u,k,m,n,x,y,z,minn;
int main()
{
memset (a,0x3f,sizeof(a));
memset (d,0x3f,sizeof(d));
for (int i=1;i<=7;i++)
{
cin >>u;
if (u)
h[i]/=2;
}
cin >>s >>t >>m;
for (int i=1;i<=m;i++)
{
cin >>x >>y >>z;
a[x][y]=a[y][x]=h[z];
}
for (int i=1;i<=100;i++)
a[i][i]=0,d[i]=a[s][i];
v[s]=1;
for (int i=1;i<=100;i++)
{
k=0; minn=d[0];
for (int j=1;j<=100;j++)
if (v[j]==0 and d[j]<minn)
{
minn=d[j];
k=j;
}
v[k]=1;
for (int j=1;j<=100;j++)
if (d[j]>d[k]+a[k][j] and v[j]==0)
d[j]=d[k]+a[k][j];
}
cout <<d[t];
return 0;
}