单源最短路径
单源最短路径算法,其实就是进行松驰的算法。
有Dijkstra/Bellman ford/SPFA 这三种算法
如图所示:
算法模板:
共用代码
#define NMAX 105
#define EMAX 10005
int head[NMAX];
int dist[NMAX];
int ver[EMAX];
int nxt[EMAX];
int wi[EMAX];
int tot;
void add(int u,int v,int w){
ver[++tot] = v;
nxt[tot] = head[u];
head[u] = tot;
wi[tot] = w;
}
bool relax(int u,int v,int w){
if ( dist[v] > dist[u] + w ){
dist[v] = dist[u] + w;
return true;
}
return false;
}
void reset(){
memset(ver,0,sizeof(ver));
memset(head,0,sizeof(head));
memset(wi,0,sizeof(wi));
memset(nxt,0,sizeof(nxt));
tot = 0;
}
Bellman ford
int bellmanford(int n,int source,int target){
dist[source] = 0;
for( int i=1;i<n;i++ ){
bool flag = false;//tle解决方案
for(int u=1;u<=n;++u){
for( int e=head[u];e>0;e=nxt[e] ){
int v = ver[e];
int w = wi[e];
flag = relax(u,v,w) || flag;
}
}
if ( !flag ) break;
}
return dist[target];
}
spfa
int spfa(int n,int source,int to){
memset(bv,0,sizeof(bv));
dist[source] = 0;
list<int> li;
li.push_back(source);
//bv是用来判断是否在队列中的
//并不是 是否已经被访问过。这点与dijkstra不同
bv[source] = true;
while(!li.empty()){
int u = li.front();
li.pop_front();
bv[u] = false;
for(int e=head[u];e;e=nxt[e]){
int v = ver[e];
if(dist[v]>dist[u] + wi[e]){
dist[v] =dist[u] + wi[e];
if ( !bv[v]){
li.push_back(v);
bv[v] = true;
}
}
}
}
return dist[to];
}
Dijkstra
int dijkstra(int n,int source,int to){
memset(bv,0,sizeof(bv));
dist[source] = 0;
priority_queue<pair<int,int>> q;
q.push(pair<int,int>(0,source));
while(!q.empty()){
int u = q.top().second;
q.pop();
if ( bv[u]) continue;
bv[u] = true;
for( int e=head[u];e>0;e=nxt[e]){
int v = ver[e];
if ( dist[v] > dist[u] + wi[e]) {
dist[v] = dist[u] + wi[e];
q.push(pair<int,int>(-dist[v],v));
}
}
}
return dist[to];
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本