最短路模板
1.无优化dijkstra,
vis[i]代表是否已选入路径,第1模板题
#include<bits/stdc++.h> using namespace std; int n,m,s,tot=0,dis[10005],head[500005],mi,t; bool vis[10005]; struct Edge{ int next,to,w; }h[500005]; void insert(int u,int v,int w){ h[++tot].next=head[u]; h[tot].to=v; h[tot].w=w; head[u]=tot; } void dijkstra(){ for(int i=1;i<=n;i++) dis[i]=2147483647; dis[s]=0; for(int i=1;i<=n;i++){ mi=214748364,t=-1; for(int j=1;j<=n;j++){ if(!vis[j] && dis[j]<mi){ mi=dis[j]; t=j; } } if(t==-1) break; vis[t]=1; for(int j=head[t];j;j=h[j].next) { if(!vis[h[j].to]) dis[h[j].to]=min(dis[h[j].to],h[j].w+dis[t]); } } } int main(){ cin>>n>>m>>s; for(int i=1,u,v,w;i<=m;i++){ cin>>u>>v>>w; insert(u,v,w); } dijkstra(); for(int i=1; i<=n; i++) printf("%d ",dis[i]); return 0; }
2.spfa vis[i]代表是否在队列队列,还可以退vis
#include<bits/stdc++.h> const long long inf=2147483647; const int maxn=10005; const int maxm=500005; using namespace std; int n,m,s,cnt; long long dis[maxn]; int vis[maxn],head[maxm]; struct Edge { int next,to,dis; }e[maxm]; void insert(int u,int v,int w) { e[++cnt].next=head[u]; e[cnt].to=v; e[cnt].dis=w; head[u]=cnt; } void spfa() { queue<int> q; for(int i=1;i<=n;i++) dis[i]=inf; q.push(s); dis[s]=0; vis[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i; i=e[i].next) { int v=e[i].to; if(dis[v]>dis[u]+e[i].dis) //如果有最短路就更改 { dis[v]=dis[u]+e[i].dis; if(!vis[v]) //未入队则入队 { vis[v]=1; //标记入队 q.push(v); } } } vis[u]=0; } } int main(){ cin>>n>>m>>s; for(int i=1; i<=m; i++){ int u,v,w; cin>>u>>v>>w; insert(u,v,w);} spfa(); for(int i=1; i<=n; i++) if(s==i) cout<<0<<" "; else cout<<dis[i]<<" "; return 0; }
3.堆优化dijkstra
直接把dis按照瞬时值放入,就算更新也没办法,导致存在小的却在队列中故需优化。按需比较后放
#include <bits/stdc++.h> #define ll long long #define rep(i,x,y) for(register int i=x;i<=y;i++) #define N 100005 #define M 500005 #define inf 2147483647 using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-48;ch=getchar();} return x*f;} int n,m,s,cnt,head[N],dis[N],vis[N]; struct node{int v,w,next;}e[M]; inline void insert(int u,int v,int w){ e[++cnt]=(node){v,w,head[u]};head[u]=cnt;} struct nodex{ int u,d; bool operator <(const nodex& a)const{return d>a.d;} };priority_queue<nodex> q; inline void dijkstra(){ rep(i,1,n) dis[i]=inf,vis[i]=0; dis[s]=0; q.push((nodex){s,0}); while(!q.empty()){ int u=q.top().u,d=q.top().d;q.pop(); if(vis[u]) continue;//可能前面存在两条边同时扩展到了该节点,将其入队两次,需要弹出节省空间 vis[u]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[u]+w<dis[v]){ dis[v]=dis[u]+w; if(!vis[v])q.push((nodex){v,dis[v]}); } } } } int main(){ // freopen("1.in","r",stdin); n=read(),m=read(),s=read(); for(int i=1;i<=m;i++){ int x=read(),y=read(),z=read(); insert(x,y,z);} dijkstra(); rep(i,1,n) printf("%d ",dis[i]); return 0; }