zoukankan      html  css  js  c++  java
  • 堆优DIJ模板

    Dij:贪心思想的单源最短路,时间复杂度O(n^2)。

    Dij算法流程:

    1. d数组记录源点s到每个点的距离,若无边则设为inf,标记源点;
    2. 选出d数组中未标记的最小值,该节点记为k,并标记k为已求出最短路;
    3. 枚举每个节点(记为j),若经过k到达j的路径<d[j]且未标记,则更新d[j];
    4. 重复2、3步n次;
    5. d[v]为s-v的最短路;

    堆优Dij:即用堆优化的dij算法,时间复杂度O(nlogn);(但是据说跑起来比spfa快?求神犇解释)

    堆优Dij算法流程:

    1. q为priority_queue,优先队列记录一个二元组,分别为索引位置和数值;

      d数组记录源点s到每个点的距离,若无边则设为inf;

    2. 源点入队;
    3. 队首出队并标记队首;
    4. 遍历队首的邻接点,若可松弛,则更新该邻接点的最短路并将该节点压入优先队列;

    不知道为什么,写出来的spfa和堆优dij的唯一区别就是spfa的队列变成了dij的优先队列,也不知道这样对不对,若有错误希望大家指出。

    经测试,其实无需标记,堆优dij是照着dij模板改的,求解释。。。

    例题:Codevs2038香甜的黄油

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<queue>
     4 #include<vector>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 struct edge{
     9     int to;
    10     int w;
    11     int next;
    12 };
    13 
    14 struct node{
    15     int index,value;
    16     node(){};
    17     node(int x,int y){index=x;value=y;}//构造函数
    18     friend bool operator < (node a,node b){
    19         return a.value>b.value;
    20     }//重载小于号
    21 };
    22 
    23 priority_queue<node> q;
    24 edge e[10000];
    25 int ne=0,head[1000],d[1000],a[1000],answer[1000]={0};
    26 bool b[1000];
    27 
    28 void add(int a,int b,int c){
    29     e[++ne].to=b;e[ne].w=c;e[ne].next=head[a];head[a]=ne;
    30 }
    31 
    32 void dij(int k){//k为源点编号
    33     int i,v;
    34     node u;
    35     memset(d,127,sizeof(d));
    36     memset(b,0,sizeof(b));//初始化
    37     d[k]=0;
    38     //b[k]=true;
    39     q.push(node(k,0));//构造并压入源点
    40     while(!q.empty()){
    41         u=q.top();q.pop();//弹出队首
    42         //if(b[u.index])continue;
    43         //b[u.index]=true;//标记
    44         for(i=head[u.index];i!=-1;i=e[i].next){//遍历邻接点
    45             v=e[i].to;
    46             if(u.value+e[i].w<d[v]/*&&b[v]==false*/){
    47                 d[v]=u.value+e[i].w;//松弛操作
    48                 q.push(node(v,d[v]));//压入新节点
    49             }
    50         }
    51     }
    52 }
    53 
    54 int main(){
    55     int n,p,c,ans=999999999,i,j,u,v,w;
    56     memset(head,-1,sizeof(head));
    57     memset(e,0,sizeof(e));
    58     scanf("%d%d%d",&n,&p,&c);
    59     for(i=1;i<=n;i++)scanf("%d",&a[i]);
    60     for(i=1;i<=c;i++){
    61         scanf("%d%d%d",&u,&v,&w);
    62         add(u,v,w);
    63         add(v,u,w);//连边
    64     }
    65     for(i=1;i<=p;i++){
    66         dij(i);
    67         int sum=0;
    68         for(j=1;j<=n;j++)sum+=d[a[j]];
    69         ans=min(ans,sum);
    70     }
    71     printf("%d
    ",ans);
    72 }

     

     

  • 相关阅读:
    HDU 5744
    HDU 5815
    POJ 1269
    HDU 5742
    HDU 4609
    fzu 1150 Farmer Bill's Problem
    fzu 1002 HangOver
    fzu 1001 Duplicate Pair
    fzu 1150 Farmer Bill's Problem
    fzu 1182 Argus 优先队列
  • 原文地址:https://www.cnblogs.com/y-m-y/p/5730794.html
Copyright © 2011-2022 走看看