• Dijkstra模板


    (一)首先明确Dijkstra算法是干什么的
        是解决赋权图单源最短路问题的。
    (二)算法的基本思想:
      
      先确定始点到某一点的最短通路,然后利用这个结果再去求始点到另一个点的最短通路,直到找到始点a到终点z的最短通路。
    (三)算法的基本步骤:
        1.将点集V分成两个子集T和S,初始时,将始点a放进T集合,S=V-T,DT(t)=w(a,t),DT(t)表示在集合S中的任一点t到始点a的最短通路,t与a相邻,否则DT(t)为正无穷。
        2.找出集合S中DT(t)值最小对应的顶点x(他距离a的距离最短)。将x从S集合中删除,将x放进T集合。如果此时S集合为空集,结束,否则,转到步骤三。
        3.对集合S中的每一个元素t,更新t到a的距离,DT(t)=min(DT(t),DT(x)+w(x,t)),转到步骤二。
    (四)三点说明
        1.Dijkstra算法只能解决权值为正的赋权图的单源最短路问题。
        2.每个点到始点的最短距离都已经求出。
        3.考虑重边。
     1 void Dijkstra(int n,int x)//n表示n个结点,x表示源点
     2 {
     3     int i,p,j,min;
     4     for (i=1;i<=n;i++)//初始化
     5     {
     6         dis[i]=map[x][i];//dis[i]表示x到i节点的最短路,map[i][j]表示i节点到j节点的距离,   i,j相邻
     7         visited[i]=0;
     8     }
     9     visited[x]=1;//将x结点放入T集合
    10     for (i=1;i<=n;i++)
    11     {
    12         min=INF;
    13         for (j=1;j<=n;j++)
    14         {
    15             if(!visited[j] && dis[j]<min)//从S集合中找一个到x节点最近的点J
    16             {
    17                 p=j;
    18                 min=dis[j];
    19             }
    20         }
    21         visited[p]=1;//将J节点放进T集合
    22         for (j=1;j<=n;j++)
    23         {
    24             if(!visited[j] && dis[p]+map[p][j]<dis[j])//将S集合中的所有节点到X节点的距离更新一遍
    25             {
    26                     dis[j]=dis[p]+map[p][j];
    27             }
    28         }
    29     }
    30 }
    下面放已经AC的题
    HDU1874
     1 #include <iostream>
     2 #include <cstring>
     3 #include <stdio.h>
     4 
     5 using namespace std;
     6 int n,m;
     7 int map[210][210],dis[210],visited[210];
     8 const int inf=1<<30;
     9 void Dijkstra(int x,int y)
    10 {
    11     int min,i,j,pos;
    12     memset(visited,0,sizeof(visited));
    13     for(i=0;i<n;i++)
    14     {
    15         dis[i]=map[x][i];
    16     }
    17     visited[x]=1;
    18     for(i=1;i<n;i++)
    19     {
    20         min = inf;
    21         for(j=0;j<n;j++)
    22         {
    23             if(dis[j]<min&&!visited[j])
    24             {
    25                 pos=j;
    26                 min=dis[j];
    27             }
    28         }
    29         visited[pos]=1;
    30         for(j=0;j<n;j++)
    31         {
    32             if(!visited[j]&&dis[pos]+map[pos][j]<dis[j])
    33                 dis[j]=dis[pos]+map[pos][j];
    34         }
    35     }
    36 
    37 }
    38 int main()
    39 {
    40     int start,end,j,a,b,t,i;
    41     while(~scanf("%d%d",&n,&m))
    42     {
    43         for(i=0;i<n;i++)
    44         {
    45             for(j=0;j<n;j++)
    46             map[i][j]=inf;
    47             map[i][i]=0;
    48         }
    49         while(m--)
    50         {
    51             scanf("%d%d%d",&a,&b,&t);
    52             if(map[a][b]>t)
    53                 map[a][b]=map[b][a]=t;
    54         }
    55         scanf("%d%d",&start,&end);
    56         Dijkstra(start,end);
    57         printf("%d
    ",dis[end]==inf?-1:dis[end]);
    58     }
    59     return 0;
    60 }
    HDU2544优先队列解决
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<stack>
     8 #include<queue>
     9 #include<vector>
    10 using namespace std;
    11 #define INF  0x3f3f3f3f   //定义一个很大的数
    12 struct Node
    13 {
    14     int num,val;   //存放结点编号和到初始点的距离
    15 }nod;
    16 priority_queue<Node> qq;;   //优先从小到大
    17 bool operator < (Node a,Node b)
    18 {
    19     if(a.val == b.val) return a.num>b.num;
    20     return a.val>b.val;              //先出小
    21 }
    22 int book[100];  //检查这个点是否用过
    23 int dis[100];     //到原点最短距离
    24 int D[100][100];  //记录路径长度
    25 int V,E;
    26 int main()
    27 {
    28     int a,b,d;
    29     while(cin>>V>>E && V&& E)  //输入顶点数和边数
    30     {
    31         while(!qq.empty()) qq.pop(); //清空
    32         memset(book,0,sizeof(book));
    33         memset(D,-1,sizeof(D));
    34         for(int i=0;i<E;i++)
    35         {
    36             cin>>a>>b>>d;
    37             D[a][b] = D[b][a] = d;
    38         }
    39         for(int i=2;i<=V;i++)
    40             dis[i]=INF;
    41             dis[1]=0;
    42             nod.num=1;
    43             nod.val=0;
    44             qq.push(nod);   //将起点放入队列
    45         while(!qq.empty())  //不为空时
    46         {
    47             for(int i=2;i<=V;i++)
    48             {
    49                 if(D[qq.top().num][i] != -1  &&dis[i]>dis[qq.top().num] + D[qq.top().num][i])
    50                 {
    51                     dis[i]=dis[qq.top().num] + D[qq.top().num][i];
    52                     nod.num=i; nod.val=dis[i];
    53                     qq.push(nod);
    54                 }
    55             }
    56             qq.pop();
    57         }
    58         cout<<dis[V]<<endl;
    59     }
    60     return 0;
    61 }

     

     
  • 相关阅读:
    double保存小数点后两位
    二维数组做函数参数,及地址问题
    解决应用程序无法正常启动0xcxxxxxxxxxx问题
    docker+selenium grid解决node执行经常卡死
    docker+selenium Grid搭建自动化分布式测试环境
    Docker+Selenium Grid+Python搭建分布式测试环境
    xshell无法连接Ubuntu的解决办法
    docker获取镜像很慢解决办法
    django使用ajax传输数据
    $.ajax()所有参数详解
  • 原文地址:https://www.cnblogs.com/--lr/p/6701578.html
Copyright © 2020-2023  润新知