zoukankan      html  css  js  c++  java
  • dijkstra模板题 洛谷1339 邻接图建边

    题目链接:https://www.luogu.com.cn/problem/P1339

    朴素dijkstra算法的复杂度是O(n^2),用堆优化的dijkstra复杂度是O(nlogn)的。在本题中前向星存边的时间消耗大约是113ms,空间消耗大约是8M,而在矩阵存边中时间消耗大约是125ms,空间消耗大约是30M,可见前向星是非常节省空间的。但点多边少的时候还是用前向星比较好。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define dbg(args) cout<<#args<<":"<<args<<endl;
    17 #define inf 0x3f3f3f3f
    18 const int maxn=1e6+10;
    19 int n,m,t;
    20 int d[maxn],head[maxn],nxt[maxn];
    21 int e=0;
    22 struct node{
    23     int v,dis;
    24     node(int dis,int v):dis(dis),v(v){}
    25     node(){}
    26     bool  operator < (const node& a)const
    27     {
    28         return dis>a.dis;//priority_queue中按照dis递增 
    29     }
    30 };
    31 struct edge{
    32     int v,w;
    33 }p[maxn];
    34 void init()
    35 {
    36     mem(head,-1);
    37     mem(nxt,-1);
    38     e=0;
    39 }
    40 void addedge(int u,int v,int w)//邻接图单向建边 
    41 {
    42     p[e].v=v;
    43     p[e].w=w;
    44     nxt[e]=head[u];
    45     head[u]=e++;
    46 }
    47 void dijkstra(int src)
    48 {
    49     f(i,1,n)d[i]=inf;
    50     d[src]=0;
    51     priority_queue<node> q;
    52     q.push(node(0,src));
    53     while(!q.empty())
    54     {
    55         node u=q.top();
    56         q.pop();
    57         if(d[u.v]<u.dis)continue;
    58         int x=u.v;
    59         for(int i=head[x];~i;i=nxt[i])
    60         {
    61             if(d[p[i].v]>d[x]+p[i].w)
    62             {
    63                 d[p[i].v]=d[x]+p[i].w;
    64                 q.push(node(d[p[i].v],p[i].v));
    65             }
    66         }
    67     }
    68  } 
    69 int main()
    70 {
    71     //freopen("input.txt","r",stdin);
    72     //freopen("output.txt","w",stdout);
    73     std::ios::sync_with_stdio(false);
    74     int st,ed;
    75     scanf("%d%d%d%d",&n,&m,&st,&ed);
    76     int u,v,w;
    77     init();
    78     f(i,1,m)
    79     {
    80         scanf("%d%d%d",&u,&v,&w);
    81         addedge(u,v,w);
    82         addedge(v,u,w);
    83      } 
    84      dijkstra(st);
    85      pf("%d",d[ed]);
    86  } 

    邻接矩阵存边的代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define P pair<int,int> 
    17 #define  mp(a,b) make_pair((a),(b))
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x3f3f3f3f
    20 const int maxn=1e6+10;
    21 #define maxm 3000
    22 int n,m,t;
    23 int edge[maxm][maxm],d[maxm];
    24 void init()
    25 {
    26     f(i,1,n)
    27         f(j,1,n)edge[i][j]=inf;
    28 }
    29 void dijkstra(int src)
    30 {
    31     f(i,1,n)d[i]=inf;
    32     d[src]=0;
    33     priority_queue<P,vector<P>,greater<P> >q;//先定义队列中的元素类型,在定义存放存放该元素的容器,最后决定是最大堆还是最小堆 
    34     q.push(mp(0,src));
    35     while(!q.empty())
    36     {
    37         P now=q.top();
    38         q.pop();
    39         if(d[now.second]<now.first)continue;
    40         int u=now.second;
    41         f(i,1,n)
    42         {
    43             if(edge[u][i]!=inf&&d[i]>d[u]+edge[u][i])
    44             {
    45                 d[i]=d[u]+edge[u][i];
    46                 q.push(mp(d[i],i));
    47             }
    48         }
    49     }
    50 }
    51 int main()
    52 {
    53     //freopen("1339.txt","r",stdin);
    54     //freopen("output.txt","w",stdout);
    55     //std::ios::sync_with_stdio(false);
    56     int st,ed;
    57        cin>>n>>m>>st>>ed;
    58            init();
    59         int u,v,w;
    60         for(int i=0;i<m;i++)
    61         {
    62             scanf("%d%d%d",&u,&v,&w);
    63             if(edge[u][v]>w)edge[u][v]=w,edge[v][u]=w;
    64         }
    65         dijkstra(st);
    66         cout<<d[ed]<<endl;
    67  } 

     

  • 相关阅读:
    【转载】Android IntentService使用全面介绍及源码解析
    【转载】作为Android开发者,你真的熟悉Activity吗?
    【转载】从使用到原理学习Java线程池
    Linux 基础知识+常见命令
    Python中的字典合并
    Python的__hash__函数和__eq__函数
    C#中实现Hash应用
    深入理解python元类
    Docker搭建Gitlab服务器
    python的加密方式
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12550260.html
Copyright © 2011-2022 走看看