SPFA
时间复杂度
伪代码
Queue q
q.add(s) // s的距离初始为0, 其他顶点的距离初始为Infinity
while(!q.isEmpty())
v = q.remove()
for (w : v.adjs) // w是v的邻接顶点
if(dv + d(v, w) < dw)
dw = dv + d(v, w)
if(!q.contains(w)) //检查w是否在当前队列中,不在则入队
q.add(w)
时间复杂度分析
SPFA算法过程中,顶点一层一层地入队出队,一张图最多有
除第
Acwing 1129.热浪
德克萨斯纯朴的民众们这个夏天正在遭受巨大的热浪!!!
他们的德克萨斯长角牛吃起来不错,可是它们并不是很擅长生产富含奶油的乳制品。
农夫 John 此时身先士卒地承担起向德克萨斯运送大量的营养冰凉的牛奶的重任,以减轻德克萨斯人忍受酷暑的痛苦。
John 已经研究过可以把牛奶从威斯康星运送到德克萨斯州的路线。
这些路线包括起始点和终点一共有
除了起点和终点外的每个城镇都由 双向道路 连向至少两个其它的城镇。
每条道路有一个通过费用(包括油费,过路费等等)。
给定一个地图,包含
每条道路由道路的起点
求从起始的城镇
输入格式
第一行:
第
输出格式
一个单独的整数表示从
数据保证至少存在一条道路。
数据范围
输入样例:
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
输出样例:
7
思路:
可以看出是单源最短路问题, 选择 SPFA
代码:
SPFA, 循环队列实现
...
const int N = 2510, M = 6200 *2 + 10;
int n,m,S,T;
int h[N], e[M], w[M] ,ne[M], idx;
int dist[N], q[N];
bool st[N];
void add(int a, int b, int c){
e[idx]= b, w[idx] = c, ne[idx] = h[a] ,h[a] = idx ++;
}
void spfa(){
memset(dist, 0X3f, sizeof dist);
dist[S] = 0;
int hh = 0, tt = 1;
q[0] = S, st[S] = true;
while(hh != tt){
int t = q[hh++];
if(hh == N) hh=0;
st[t] = false;
for(int i=h[t]; ~i; i =ne[i]){
int j = e[i];
if(dist[j]>dist[t]+w[i]){
dist[j] = dist[t] + w[i];
if(!st[j]){
q[tt++] = j;
if(tt==n) tt = 0;
st[j] = true;
}
}
}
}
}
int main(){
cin>>n>>m>>S>>T;
memset(h, -1, sizeof h);
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c), add(b,a,c);
}
spfa();
cout<<dist[T]<<endl;
return 0;
}