zoukankan      html  css  js  c++  java
  • 单源最短路模板(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 }
  • 相关阅读:
    CSS 中z-index全解析(摘自阿里西西)
    Video标签的使用
    HTML标签解释大全
    在html中插入音频
    ABAP更改现有程序
    乱糟糟的笔记
    ABAP提示信息对话框
    【学习】几种查找增强的方法
    【学习】ABAP OLE 对EXCEL的处理
    【转载】ABAP-如何读取内表的字段名称
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/8496757.html
Copyright © 2011-2022 走看看