图论之dijkstra

来源:互联网 发布:真空淬火油数据 编辑:程序博客网 时间:2024/06/05 20:48

di’jkstra是由迪杰斯特拉提出的一种图论算法,用于求一个点到其他所有点的最短距离。
迪哥照片
dijkstra的核心思想就是将所有的点分成两个集合A,B,从B集合中找到一个离A集合内的点最近的点,把他加入A集合,然后再用这个点去迭代其他所有点。
注意dijkstra不能用于有负权的图(要不然永远找不到最短路径,每次加一边就会变小)
核心代码;

void dijkstra(int st){    memset(vis,0,sizeof(vis));//vis数组用来表示该点是在集合A还是集合B;     memset(dis,10,sizeof(dis));//dis[I]表示起点到I点的最短距离。初始时都付为正无穷;     for(int i=1;i<=n;i++)    dis[i]=a[st][i]; //现将与起点直接相连的点的距离赋值     dis[st]=0;//自己到自己距离是0;     vis[st]=1;//刚开始只有起点在A集合;     for(int i=1;i<n;i++)//注意循环次数是n-1次,因为起点已经在A集合里面了;     {        int minn=999999;        int k=0;        for(int j=1;j<=n;j++) //找到与A集合内的点距离最近的B集合内的点;         {            if(dis[j]<minn)            {                minn=dis[j];                k=j;            }            if(k==0) return;//如果K==0说明找不到了,结束循环。             vis[k]=1;//每次把找到的这个点加入A集合;             for(int j=1;j<=n;j++)//用找到的K点迭代;             {                if(dis[k]+a[k][j]<dis[j])                dis[j]=dis[k]+a[k][j];            }        }    }}

例题1
热浪!
相信大家都知道这道题,如果不知道可以去洛谷上搜索,我就不贴题目了。
热浪这道题的话就是纯粹的dijkstra模版,只要照着我上面的模版敲一遍就过了。
例题2
贝西回家(Bessia Come Home)
这道题的话其实也是模版,将52个农场看成52个点,然后以Z农场为起点做dijkstra,
再枚举一边选最小值。
但是这道题输入比较麻烦,因为他告诉你的农场是字母,我们可以在输入时将字母转化为数字,也可以直接用字母作为二维数组的下标。然后记得建立邻接矩阵的时候要判断重边(就是他先告诉你1到2距离是3,又告诉你1到2距离是4,这时候我们当然要选择最小的)
好了就到这里吧!GG