HDU - 2544 最短路 (dijkstra 优先队列优化)

题目链接

是一个求最短路的模板题(题目中都写最短路23333)。

        一般建图比较方便的是用邻接矩阵的方法,但是对于dijkstra算法来说,其时间复杂度为O(n^{2})。

       我们有一个更好的优化算法:即利用优先队列(小根堆)进行时间上的优化,复杂度可以达到O((m+n)logm)。

(题外话:vector真心真心好用,vector是已经封装了的,又不像链表那么麻烦,最关键的是,大部分在图上的操作用邻接表(vector)比邻接矩阵效率要高很多)

复杂度分析论证:

下面附上这道题的代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#define maxn 10005

using namespace std;
int dis[maxn];
struct Edge
{
     int u,v,w;
     Edge(int uu,int vv,int ww):u(uu),v(vv),w(ww){}
};
struct Node
{
     int id;
     int w;//从源点到这个点的最短路径,一直更新给dis[]
     bool operator<(const Node &b)
          const {w>b.w;}
}mid;
vector<Edge>e[maxn<<1];
priority_queue<Node>pq;

void dijk(int s)
{
     pq.push(Node{s,0});
     dis[s]=0;
     while(!pq.empty())//可以直接拿出最短的那条边
     {
          mid=pq.top();
          pq.pop();
          int card=mid.id;
          if(mid.w!=dis[card])
               continue;
          for(int i=0;i<e[card].size();i++)
          {
               if(dis[e[card][i].v]>dis[card]+e[card][i].w)//一直更新
               {
                    dis[e[card][i].v]=dis[card]+e[card][i].w;
                    pq.push(Node{e[card][i].v,dis[e[card][i].v]});
               }
          }
     }
}
int main(void)
{
     int n,m;
     int a,b,c;
     while(~scanf("%d%d",&n,&m)&&(n+m))
     {
          //memset(vis,false,sizeof(vis));
          memset(dis,0x3f,sizeof(dis));
          for(int i=1;i<=n;i++)
               e[i].clear();
          //
          for(int i=1;i<=m;i++)
          {
               scanf("%d%d%d",&a,&b,&c);
               e[b].push_back(Edge(b,a,c));
               e[a].push_back(Edge(a,b,c));//建图
          }
          dijk(1);
          printf("%d\n",dis[n]);
     }
     return 0;
}

呼呼

猜你喜欢

转载自blog.csdn.net/destiny1507/article/details/81488634