最短路问题有3种常用方法:
Floyd,Dijkstra,SPFA
以下为总结代码(参考)
Floyd
可求图中任意两点间的最短路
时间复杂度上有很大不足----O(N^3)
代码难度简单
#include<bits/stdc++.h> typedef long long ll; using namespace std; ll n,m,k; ll s[1005][1005]; int main() { memset(s,0x3f,sizeof(s)); scanf("%lld%lld%lld",&n,&m,&k); for(ll i=1;i<=m;i++) { ll x,y,z; scanf("%lld%lld%lld",&x,&y,&z); s[x][y]=min(s[x][y],z); } for(ll i=1;i<=n;i++) { s[i][i]=0; for(ll j=1;j<=n;j++) { s[j][j]=0; for(ll o=1;o<=n;o++) { s[o][o]=0; s[j][o]=min(s[j][o],s[j][i]+s[i][o]); } } } for(ll i=1;i<=k;i++) { ll b,e; scanf("%lld%lld",&b,&e); if(s[b][e]<=0x3f3f3f3f/2) printf("%lld\n",s[b][e]); else printf("impossible\n"); } return 0; }
Dijkstra
可求单源最短路
一般时间复杂度----O(n^2)
优化后时间复杂度----O(m logn)
代码难度一般
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 ll n,m,now; 5 ll s[1005][1005],dis[1005]; 6 bool vi[1005]; 7 int main() 8 { 9 scanf("%lld%lld",&n,&m); 10 memset(s,0x3f,sizeof(s)); 11 for(ll i=1;i<=n;i++) s[i][i]=0; 12 for(ll i=1;i<=m;i++) 13 { 14 ll x,y,z; 15 scanf("%lld%lld%lld",&x,&y,&z); 16 s[x][y]=min(s[x][y],z); 17 } 18 memset(dis,0x3f,sizeof(dis)); 19 dis[1]=0; 20 for(ll i=1;i<n;i++) 21 { 22 ll t=0; 23 for(ll j=1;j<=n;j++) 24 { 25 if((dis[j]<dis[t]||t==0)&&!vi[j]) 26 { 27 t=j; 28 } 29 } 30 vi[t]=1; 31 for(ll j=1;j<=n;j++) 32 { 33 dis[j]=min(dis[j],dis[t]+s[t][j]); 34 } 35 } 36 if(dis[n]<0x3f3f3f3f/2) 37 printf("%lld",dis[n]); 38 else printf("-1"); 39 return 0; 40 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef pair<long long,long long> pp; 4 typedef long long ll; 5 ll n,m; 6 ll fir[100005],to[100005],nxt[100005],w[100005],num; 7 ll dis[100005]; 8 bool vis[100005]; 9 void add(ll x,ll y,ll z) 10 { 11 nxt[++num]=fir[x]; 12 fir[x]=num; 13 to[num]=y; 14 w[num]=z; 15 } 16 void dj() 17 { 18 memset(dis,0x3f,sizeof(dis)); 19 memset(vis,0,sizeof(vis)); 20 priority_queue<pp,vector<pp>,greater<pp> > q; 21 q.push(make_pair(0,1)); 22 dis[1]=0; 23 while(q.size()) 24 { 25 ll u=q.top().second,diss=q.top().first; 26 q.pop(); 27 if(vis[u]) continue; 28 vis[u]=1; 29 for(ll i=fir[u];i;i=nxt[i]) 30 { 31 ll v=to[i]; 32 if(dis[v]>dis[u]+w[i]) 33 { 34 dis[v]=dis[u]+w[i]; 35 36 q.push(make_pair(dis[v],v)); 37 } 38 } 39 } 40 } 41 int main() 42 { 43 scanf("%lld%lld",&n,&m); 44 for(ll i=1;i<=m;i++) 45 { 46 ll x,y,z; 47 scanf("%lld%lld%lld",&x,&y,&z); 48 add(x,y,z); 49 } 50 dj(); 51 if(dis[n]<0x3f3f3f3f/2) printf("%lld",dis[n]); 52 else printf("-1"); 53 return 0; 54 }
SPFA
可求单源最短路
时间复杂度----O(k m)
代码难度一般
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 struct edge 5 { 6 ll nxt,to,w; 7 }e[100005]; 8 ll n,m; 9 ll num,fir[100005],dis[100005],vis[100005]; 10 void add(ll x,ll y,ll z) 11 { 12 e[++num].nxt=fir[x]; 13 fir[x]=num; 14 e[num].to=y; 15 e[num].w=z; 16 } 17 void spfa() 18 { 19 memset(dis,0x3f,sizeof(dis)); 20 dis[1]=0; 21 queue<ll> q; 22 q.push(1); 23 while(q.size()) 24 { 25 ll u=q.front();q.pop(); 26 vis[u]=0; 27 for(ll i=fir[u],v;v=e[i].to,i;i=e[i].nxt) 28 { 29 if(dis[v]>dis[u]+e[i].w) 30 { 31 dis[v]=dis[u]+e[i].w; 32 if(!vis[v]) 33 { 34 vis[v]=1; 35 q.push(v); 36 } 37 } 38 } 39 } 40 } 41 int main() 42 { 43 scanf("%lld%lld",&n,&m); 44 for(ll i=1;i<=m;i++) 45 { 46 ll x,y,z; 47 scanf("%lld%lld%lld",&x,&y,&z); 48 add(x,y,z); 49 } 50 spfa(); 51 if(dis[n]<0x3f3f3f3f/2) 52 printf("%lld",dis[n]); 53 else printf("impossible"); 54 return 0; 55 }
有不足之处可随时评论