最短路径
算法一 :迪杰斯特拉
算法详情:贪心 维护一个 dis 数组 进行 松弛操作
适用: 单源最短路
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; const int inf = 0x3f3f3f; int n,m,s,t,u,v,w; int g[10005][10005]; int dis[10005]; bool vis[10005] ; void dij(int s ) { f(i,1,n)dis[i]=g[s][i]; vis[s] =1; dis[s] =0; f(i,1,n-1) { int mm = inf,pos; f(j,1,n) { if(!vis[j] && dis[j]<mm) { mm =dis[j]; pos =j; } } if(mm==inf ) break; vis[pos] =1; f(j,1,n) { if(!vis[j] && dis[pos]+g[pos][j]<dis[j]) dis[j]=dis[pos]+g[pos][j]; } } } void dijkstra(int s){ for(int i = 1; i <= n; i++) dis[i] = g[s][i]; vis[s] = 1; dis[s] = 0; for(int i = 1; i < n; i++){ int min = inf, pos; for(int j = 1; j <= n; j++){ if(!vis[j] && dis[j] < min){ min = dis[j]; pos = j; } } if(min == inf) break; vis[pos] = 1; for(int j = 1; j <= n; j++){ if(!vis[j] && dis[pos] + g[pos][j] < dis[j]){ dis[j] = dis[pos] + g[pos][j]; } } } } int main() { LOACL CLR(g,inf); CLR(vis,false); cin>>n>>m>>s>>t; f(i,1,n)g[i][i]=0; f(i,1,m) { cin>>u>>v>>w; g[u][v]=min(g[u][v],w); g[v][u]=min(g[v][u],w); } dijkstra(s); cout<<dis[t]<<endl; return 0; }
算法二 :Floyd
算法详情:dp 规划
适用:多源非负环,注意 初值别太大 ,会炸int
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; const int inf = 1e4+6; const int sz = 1005; int g[sz][sz]; int n,m,u,v,w; void floyd() { f(k,1,n) f(i,1,n) f(j,1,n) g[i][j]=min(g[i][j],g[i][k]+g[k][j]); } int main() { LOACL CLR(g,inf); cin>>n>>m; f(i,1,n)g[i][i]=0; f(i,1,m) { cin>>u>>v>>w; if(w < g[u][v]) g[u][v]=g[v][u]=w; } floyd() ; f(i,1,n) { f(j,1,n) cout<<g[i][j]<<" "; cout<<endl; } return 0; }
算法二 :spfa
算法详情: 优化的bfs
适用:边数少最短路,注意,回述时候的标记取消
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); //#define add(u,v,w) (e[++tot]=(edge){v,head[u],w},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; const int sz =1e6+5; const int inf =0x3f3f3f; int n,m,s,t,u,v,w; int dis[sz], vis[sz] ; struct edge { int v,nxt,w; }e[sz<<1]; int head[sz],tot; void add(int u,int v,int w ) { e[++tot]=(edge){v,head[u],w},head[u]=tot; } void spfa() { int pos ; queue<int >q; q.push(s); vis[s]=1; dis[s]=0; while(!q.empty()) { int pos = q.front(); q.pop(); vis[pos]=0; for(int i = head[pos];i!=-1;i=e[i].nxt) { int v =e[i].v; if(dis[v]> dis[pos]+e[i].w) { dis[v] = dis[pos]+e[i].w ; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } int main() { LOACL CLR(vis,0); CLR(dis,inf); CLR(head,-1); cin>>n>>m>>s>>t; f(i,1,m) { cin>>u>>v>>w; add(u,v,w);add(v,u,w); } spfa(); cout<<dis[t]<<endl; return 0; }
不摸着石头过河,难道要在温柔乡睡到天昏地暗。