zoukankan      html  css  js  c++  java
  • Dijkstra+Heap模板

    普通Dijkstra:

     1 void DijkstraPath(int v0,int vis[],int dist[],int path[])
     2 {
     3     int onePath[maxn];
     4     int d;
     5     int k;
     6     for(int i = 0;i < n;i++)
     7     {
     8         if( vis[i] && i != v0)
     9         {
    10             cout<<"Path->";
    11             d = 0;
    12             onePath[d] = i;//添加路径上的终点
    13             k = path[i];
    14             if(k == -1)
    15             {
    16                 cout<<"No paht"<<endl;
    17             }
    18             else
    19             {
    20                 while(k != v0)
    21                 {
    22                     d++;
    23                     onePath[d] = k;
    24                     k = path[k];
    25                 }
    26                 d++;
    27                 onePath[d] = v0;//添加起点
    28                 cout<<"Start :"<<onePath[d];//起点
    29                 for(int j = d - 1;j>=0;j--)
    30                 {
    31                     cout<<onePath[j]<<" ";
    32                 }
    33                 cout<<endl;
    34             }
    35         }
    36     }
    37 }
    38 
    39 void Dijkstra(int v0)
    40 {
    41     int dist[maxn];//距离数组,每个点到v0的直接距离
    42     int path[maxn];//路径数组,记录最短路径上的前驱结点
    43     int vis[maxn];
    44     int u;//中间结点
    45     memset(dist,0,sizeof(dist));
    46     memset(path,0,sizeof(path));
    47     memset(vis,0,sizeof(vis));
    48     int mindist;
    49     for(int i = 0;i < n;i++)
    50     {
    51         dist[i] = Graph[v0][i];
    52         if(Graph[v0][i] < INF)
    53         {
    54             path[i] = v0;//开始与v0直连的点记录
    55         }
    56         else
    57         {
    58             path[i] = -1;
    59         }
    60     }
    61     vis[v0] = 1;//开始时v0加入最短路中
    62     path[v0] = 0;
    63     for(int i = 0; i < n-1;i++)
    64     {
    65         mindist = INF;
    66         for(int j = 0;j < n;j++)
    67         {
    68             if( !(vis[i]) && dist[j] < mindist)//找最短路
    69             {
    70                 mindist = dist[j];
    71                 u = j;
    72             }
    73         }
    74         vis[u] = 1;
    75         for(int i = 0 ; i < n;i++)//路径更新
    76         {
    77             if( !(vis[i]))////考虑剩下未访问的边
    78             {
    79                 if( Graph[u][i] < INF && dist[i] > dist[u] + Graph[u][i] )
    80                 //中间点的总路程比原来能直达的更短
    81                 {
    82                     dist[i] = dist[u] + Graph[u][i];
    83                     path[i] = u;//更新前驱结点
    84                 }
    85             }
    86         }
    87     }
    88     //DijkstraPath( v0, vis,dist,path);//输入最短路径
    89 }
    View Code

    优化后:

     1 const int maxn= 10000002;
     2 int n;
     3 int m;
     4 int p;
     5 int cnt;
     6 int dist[1002];
     7 int head[1002];//init -1
     8 //存放以i为起点的第一条边存储的位置//以i为起点最后的那个编号
     9 int point[1002];
    10 
    11 struct Edge//建图
    12 {
    13     int v;//edge[i]表示第i条边的终点
    14     int w;//edge[i]表示第i条边的权值 即 距离
    15     int nxt;//edge[i]表示与第i条边同起点的下一条边的存储位置(上一条边)
    16 }edge[maxn];
    17 
    18 void Add(int x,int y,int w)// x -> y == w
    19 {//链式向前星
    20     edge[++cnt].v = y;
    21     edge[cnt].w = w;
    22     edge[cnt].nxt = head[x];
    23     head[x] = cnt;
    24 }
    25 
    26 struct node
    27 {
    28     int u;
    29     int d;
    30     bool operator< (const node& rhs)const
    31     {
    32         return d >rhs.d;
    33     }
    34 };
    35 
    36 void Dijkstra(int s) 
    37 {  
    38     for(int i=1;i<=n;i++)
    39         dist[i] = (i==s)? 0:2147483647;
    40     priority_queue<node> Q; 
    41     Q.push((node){s,0});//开始结点进队
    42     while (!Q.empty()) 
    43     {
    44         node fr = Q.top(); Q.pop();
    45         int u = fr.u;//2,0
    46         int d = fr.d;
    47         //        cout<<"enqueue:u:"<<u<<" d:"<<d<<endl;
    48         //        cout<<"~~~";
    49         if (d != dist[u]) continue;//dijkstra中每个点只会出队一次 vis
    50         for (int i = head[u];i;i=edge[i].nxt) 
    51         {
    52          //           cout<<"i =="<<i<<endl;
    53             int v = edge[i].v;//第i条边的终点
    54          //           cout<<"edge["<<i<<"].v :"<<v<<" ";
    55             int w = edge[i].w;
    56            //          cout<<"edge["<<i<<"].w :"<<w<<" ";
    57           //           cout<<endl<<"~~~~~~~~~~~"<<endl;
    58             if (dist[u]+w < dist[v]) 
    59             {
    60             //            cout<<"dist["<<v<<"]"<<dist[v]<<" "<<endl;
    61             ///         cout<<"dist["<<u<<"] + w :"<<dist[u]+w<<endl;
    62               //          cout<<"~~~~~~~~~"<<endl;
    63                 dist[v] = dist[u]+w;
    64              //        cout<<"dist["<<v<<"] = "<<dist[u]+w<<endl;
    65              //           cout<<v<<"v,dist["<<v<<"] enqueue"<<endl;
    66                 Q.push((node){v,dist[v]});
    67             }
    68         }
    69     }
    70 }
    71 int main()
    72 {
    73         cin>>n>>m>>p;//p为特殊点
    74         memset(point,0,sizeof(point));
    75         memset(head,-1,sizeof(head));
    76         for(int i=1;i<=m;i++)
    77         {
    78             int x,y,z;
    79             scanf("%d%d%d",&x,&y,&z);
    80             Add(x,y,z);
    81         }
    82         //cout<<"~~~~~~~~~~~~~"<<endl;
    83         // for(int i = 1;i <= m;i++)
    84         // {
    85         //     cout<<"  head["<<i<<"]"<<head[i]<<" ||";
    86         //     cout<<"edge["<<i<<"] ="<<edge[i].v<<" next"<<edge[i].nxt<<endl;
    87         // }
    88         // cout<<"~~~~~~~~~~~~~~~~~~~~~"<<endl;
    89         Dijkstra(p);//p 到其他点的最小距离
    90         ...
    91        ....
    92        return 0;   
    93 }
    View Code

    以下题目可以拿来练练手,几乎是基本模板题

    P3371 【模板】单源最短路径(弱化版)

    P4779 【模板】单源最短路径(标准版)

    Silver Cow Party 

     
     
  • 相关阅读:
    ORACLE各种对象、概念及关系整理(一文读懂)
    Spring面试题总结及答案
    MySQL面试总结
    可变参数,你还为方法的参数而烦恼吗?可变参数,让你的头发从此“茂密”!
    java编译报错: 找不到或无法加载主类 Demo.class 的解决方法
    java编译报错 错误: 编码GBK的不可映射字符
    sql server2017开启远程连接
    sql server一些快捷方式和操作技巧
    sql server无法连接本地服务器
    phpStorm+xdebug调试(php7.3)
  • 原文地址:https://www.cnblogs.com/ygsworld/p/11222775.html
Copyright © 2011-2022 走看看