spfa算法:
在之前的bell算法上进行优化,用队列储存结点然后用栈进行操作,该进行操作的入栈,不该入的不入,这样可以减少很多无效的操作(也基于图自身的性质),在栈为空时就不再更新结点,结束操作
hdu2544
#include<iostream>
using namespace std;
const int inf=1e6;
const int num=10005;
struct edge{
int u,v,c;
edge(int a,int b,int c){
u=a;
v=b;
c=c;
}
};
vector<edge> e[num];
int n,m;
int pre[num];
using namespace std;
int spfa(int s){
int i,j;
int dis[num];
int vs[num];
int ne[num];
memset(ne,0,sizeof(ne));
ne[s]=1;
for( i=1;i<=n;i++){
dis[i]=inf;
vs[i]=0;
}
dis[s]=0;
queue<int> q;
q.push(s);
vs[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
vs[u]=0;
for(i=0;i<e[u].size();i++){
int v=e[u][i].to;
int w=e[u][i].c;
if(dis[v]>dis[u]+c){
dis[v]=dis[u]+c;
if(!vs[v]){
vs[v]=1;
q.push(v);
ne[v]++;
if(ne[v]>n) return 1;
}
}
}
}
cout<<dis[n]<<endl;
return 1;
}
int main(){
int i,j;
cin>>n>>m;
for(i=1;i<=n;i++) e[i].clear();
while(m--){
int a,b,c;
cin>>a>>b>>c;
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
spfa(1);
}
链式前向星优化:
//储存结点
void edge(int u,int v,int c){
edge[cnt].to = v;
edge[cnt].c = c;
edge[cnt].next = head[u];
head[u] = cnt++;
}
//调用
for(int i=head[u];i!=-1;i=edge[i].next)
dijkstra算法:
Dijkstra算法采用的是一种贪心思想,创建一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合,初始时,原点 s 的路径花费为 0 (dis[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把dis[m]设为w(s, m)同时把所有其他顶点的路径长度设为无穷大。初始时,集合中只有顶点s。
然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到集合中,此时完成了一个顶点,然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。
然后,又从dis中找出最小值,重复上述动作,直到集合里面包含了图的所有顶点。
#include<bits/stdc++.h>
using namespace std;
const int inf=1e6;
int n,m;
struct edge{
int f,t,c;
edge(int a,int b,int c){
f=a;
t=b;
c=c;
}
};
vector<edge> e[10005];
struct ss{
int id,dis;
ss(int a,int b){
id=a;
dis=b;
}
};
void d(){
int s=1;
int dis[10005];
int vis[10005];
for(int i=1;i<=n;i++){
dis[i]=inf;
vis[i]=0;
}
priority_queue<ss> q;
q.push(ss(s,dis[s]);
while(!q.empty()){
ss u=q.top;
q.pop();
if(vis[u.id]) continue;
vis[u.id]=1;
for(int i=1;i<=e[u.id].size();i++){
edge v=e[u.id][i];
if(vis[v.t]) continue;
if(dis[v.t]>u.dis+v.c){
dis[v.t]=u.dis+v.c;
q.push(ss(v.t,dis[v.t]));
}
}
}
}
int main(){
cin>>n>>m;
for(i=1;i<=n;i++) e[i].clear();
while(m--){
int a,b,c;
cin>>a>>b>>c;
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
d();
}