单源最短路模板(dijkstra)

单源最短路(dijkstra算法及堆优化)

弱化版题目链接

n^2 dijkstra模板

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int i,j,n,m,s,dis[10010];
 7 bool v[10010];
 8 struct Node{
 9     int to;
10     int w;
11     Node *next;
12 } node[10010];
13 Node *head[10010];
14 int main()
15 {
16     scanf("%d%d%d",&n,&m,&s);
17     for(i=1;i<=n;i++)
18     {
19         dis[i]=0x7fffffff;
20         head[i]=new Node;
21         head[i]->next=NULL;
22     }
23     int x,y,w;
24     for(i=1;i<=m;i++)
25     {
26         scanf("%d%d%d",&x,&y,&w);
27         Node *p=new Node;
28         p->next=head[x]->next;
29         head[x]->next=p;
30         p->to=y;
31         p->w=w;
32     }
33     for(Node *h=head[s]->next;h;h=h->next)
34         dis[h->to]=min(dis[h->to],h->w);    //注意可能有重边
35     v[s]=1;
36     dis[s]=0;
37     for(i=1;i<=n;i++)
38     {
39         int k=-1,minn=0x7fffffff;
40         for(j=1;j<=n;j++)
41          if(!v[j]&&dis[j]<minn)
42          {
43             minn=dis[j];
44             k=j;
45          }
46         if(k==-1) break;
47         v[k]=1;
48         for(Node *h=head[k]->next;h;h=h->next)
49             if(!v[h->to]&&dis[h->to]>dis[k]+h->w)
50             dis[h->to]=dis[k]+h->w;
51     }
52     for(i=1;i<=n;i++)
53     printf("%d ",dis[i]);
54     puts("");
55     return 0;
56 }

毒瘤标准版

题目链接:https://www.luogu.org/problemnew/show/P4779

直到做了这个题才发现我之前写的堆优化dijkstra一直是错的。。

这个堆优化其实很容易理解,将枚举最小值改为从堆中取出最小值,改变dis时入堆即可

用优先队列维护时必须有两个值:点的编号和当前的距离

以距离为标准从小到大排序, 每次取出最小的

以前错的原因:

堆中只维护了点的编号,以dis[x]排序

这样做在取出一个元素操作后,会更新它周围一圈元素的dis值,

若它周围一圈元素中有的在堆中,dis值被改变后,堆的性质会遭到破坏

然而由于弱化版太水了,我在做毒瘤版之前一直认为这是对的

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<queue>
 5 using namespace std;
 6 #define il inline
 7 #define re register
 8 #define N 100010
 9 #define M 200010
10 int n,m,s,dis[N];
11 struct NODE{
12     int p;
13     int cost;
14 };
15 struct cmp{
16     il bool operator()(NODE ZYX,NODE YSH){
17         return ZYX.cost>YSH.cost;
18     }
19 };
20 priority_queue<NODE,vector<NODE>,cmp> q;
21 il int read(){
22     int x=0; char c=getchar();
23     while(c<'0'||c>'9') c=getchar();
24     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
25     return x;
26 }
27 void write(int x){
28     if(x>9) write(x/10);
29     putchar(x%10+'0');
30 }
31 struct NODE{
32     int to,w,next;
33 } e[M];
34 int Head[N],num;
35 il void add(int x,int y,int w){
36     e[++num].to=y;
37     e[num].w=w;
38     e[num].next=Head[x];
39     Head[x]=num;
40 }
41 bool used[N];
42 int main()
43 {
44     n=read(); m=read(); s=read();
45     int x,y,w;
46     for(re int i=1;i<=m;i++){
47         x=read(); y=read(); w=read();
48         add(x,y,w);
49     }
50     memset(dis,127,sizeof(dis));
51     dis[s]=0;
52     q.push((NODE){s,0});
53     while(!q.empty()){
54         NODE k=q.top();
55         q.pop();
56         int u=k.p;
57         if(used[u]) continue;
58         used[u]=1;
59         for(re int i=Head[u];i;i=e[i].next){
60             int v=e[i].to;
61             if(dis[v]>dis[u]+e[i].w){
62                 dis[v]=dis[u]+e[i].w;
63                 q.push(NODE{v,dis[v]});
64             }
65         }
66     }
67     for(re int i=1;i<=n;i++)
68      write(dis[i]),putchar(' ');
69     return 0;
70 }
原文地址:https://www.cnblogs.com/yjkhhh/p/8496757.html