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 }

 

 
原文地址:https://www.cnblogs.com/--lr/p/6701578.html