额,博主只是做了几(约数)道题而已,写这篇小结纯粹想留作纪念(勿喷,但是可以交流)(那啥,转载的话注明一下来源。。打字不容易。。)
最短路呢,包括三种算法,但是各有各的变种,其中变化有很多。
简单记录一下。
首先是三种算法:
1、Dijkstra算法。(单源点最短路径)
双手奉上啊哈雷算法。
然后开始叙述我所理解(如有雷同。。那就雷同吧)的:
有n个点,相互之间可能有所连接或者没有,那么现在,如果让求点1到点n之间的最短路,该怎么求?
这里面有个很有趣的东西,叫做松弛,翻译过来就是这么个意思:
假如已知最短路1-3长度为5,最短路1->4长度为7(无论是1-3,还是1-4均是当前最短,也可以理解成当前最优(dp)),而3->4的长度为1,那么这个时候,明显可以知道:1->3->4的长度是小于1->4的,那么现在把1-4更新到当前最优,长度也就是变成了6。
以上就是松弛操作。也就是假设在1-n中有一个x点,且用d数组表示1~其他点的当前最优最短路,用w二维数组表示两点之间的距离,那么给定一个当前最优点y,如果d[y]>d[x]+w[x][y],是不是说明d[y]可以有更小的值呢?答案显而易见。
那么这是一个点,题目中一共n个点,那么我用每一个点都去更新1到其他点的距离,那么全部更新过后,是不是d[n]表示的就是从1~n的最短路了呢?
而这一切,每一次更细都相当于在所有任意的两个点(其中一个点是1(起点))里插入第三个点,看是否能够松弛,若能,就松弛,不能,就不管了呗。
还有,既然,n个点都要去更新一遍,那么谁先去更新呢?
答案:当然是d值最小的那个点去更新,因为用最小的去更新,才可能更新的动呀。但是既然,只需要每个点更新一次,那么要做个标记,以防更新过的点再次进行更新。
d值会越来越小,那么初值肯定是越大越好咯。
但是呢,既然d数组代表的是1到其余各点的最短距离,那么d[1]肯定是0。。
例题博客(基本上我第一次写的题博客都很长。。):Til the Cows Come Home
来啊,代码伺候!!!
int INF=0x3f3f3f3f
for(int i=1;i<=n;i++)
{
d[i]=INF;
vis[i]=0;
}
d[1]=0;
for(int i=1;i<=n;i++)//每个点都要参与更新,所以循环n次
{
int m=INF,x=-1;//m是为了找出最小那一个,x记录节点
for(int j=1;j<=n;j++)
{
if(!vis[j]&&d[