题目链接: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 }