图论之SPFA
来源:互联网 发布:2016年网络流行关键词 编辑:程序博客网 时间:2024/06/05 00:52
图论之SPFA
First:
在Bellman-ford算法中,每次都要检查所有的边。这个看起来比较浪费,对于边(x,y),如果上一次dis[x]没有改变,则本次的检查显然是多余的。
Next:
而所谓SPFA,就是在Bellman-ford算法的基础上,对迭代进行了改进。
Then:
我们只要每次都从上次刚被“松驰”过的点x,来看看x能不能松驰其它点即可完成优化。
那么如何实现呢?
SPFA算法中用BFS中的队列来存放刚被“松驰”过的点。由于顶点个数为|V|,队列如果用数组的话显然要用“循环队列”使用空间。
SPFA在形式上和宽度优先搜索非常类似,不同的是宽度优先搜索中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是一个点改进过其它的点之后,过了一段时间可能本身会再次被改进,于是再次用来改进其它的点,这样反复迭代下去。
这一点也是SPFA算法最重要的一个点,也正是这一点让SPFA能够实现求最短路。
上个伪代码:
SP_SPFA(G, s) //求单源s到其它点的最短距离
for i=1 to n do
dis[i] =∞;vis[i] =false; // 初始化每点到s距离,不在队列
dis[s] 0; //将dis[s]设为0
vis[s] =true; count = 1; //s放入队列
head = 0; tail = 0; q[0]=s; //队列头尾指针
while (count>0) do
v = q[head]; //队头节点v
for 每条边(v,i) //与v相连的每一条边
if( dis【v]+len【v][i]小于dis[i]) //不满足三角形性质
dis【i] =dis【v]+len【v][i]; //松驰dis[i]
if (vis[i] = false) //不在队列,则加入队列
vis[i] = true; count+1;
tail+1; q[tail] = i;
vis[v] =false;head+1;count-1; //v出队列
And Then:
上例题:香甜的黄油 洛谷P1828
题目描述
农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。 农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。 农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)
输入格式
第一行: 三个数:奶牛数N,牧场数(2<=P<=800),牧场间道路数C(1<=C<=1450) 第二行到第N+1行: 1到N头奶牛所在的牧场号 第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距离(1<=D<=255),当然,连接是双向的
输出格式
一行 输出奶牛必须行走的最小的距离和
样例数据
input
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
output
8
{说明: 放在4号牧场最优}
数据规模与约定
时间限制:1s1s
空间限制:256MB
上代码:
#include<bits/stdc++.h>using namespace std;struct my{ int v,y,next;}e[20000];int a[20000],len=0,cow[1000];int n,p,c;void insert(int xx,int yy,int vv){ e[++len].next=a[xx]; a[xx]=len; e[len].y=yy; e[len].v=vv;}int dis[10000],vis[10000],q[10000],minn=10000000;void spfa(int st){ memset(dis,10,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[st]=0; vis[st]=1; q[1]=st; int head=0,tail=1; while(head<tail) { int tn=q[++head]; vis[tn]=0; int te=a[tn]; for(int i=te;i;i=e[i].next) { int tmp=e[i].y; if(dis[tn]+e[i].v<dis[tmp]) { dis[tmp]=dis[tn]+e[i].v; if(!vis[tmp]) { vis[tmp]=1; q[++tail]=tmp; } } } } int num=0; for(int i=1;i<=n;i++) { num+=dis[cow[i]]; } if(num<minn) minn=num;}int main(){ cin>>n>>p>>c; for(int i=1;i<=n;i++) cin>>cow[i]; int x,y,v; for(int i=1;i<=c;i++) { cin>>x>>y>>v; insert(x,y,v); insert(y,x,v); } for(int i=1;i<=p;i++) spfa(i); cout<<minn; return 0;}
- 图论之SPFA
- 图论浅析--最短路之SPFA
- 【OI之路】03图论算法-1最短路之单源最短路(SPFA)
- 图论基本算法3之最短路径(spfa)
- BZOJ1715 SPFA 浅谈图论之负环的多重化判定
- 3259 Wormholes 之 SPFA
- 最短路之SPFA
- 图论最短路之spfa
- hdu1428之dfs+spfa
- hdu1428之spfa+dfs
- 选拔赛之 spfa
- POJ3592-图论综合题tarjan+spfa
- 图论算法——SPFA算法
- 图论基础SPFA:poj3268模板题
- SPFA算法之最短路。
- 最短路径之 SPFA
- 最短路之SPFA模板
- 最短路之SPFA模板
- 8051单片机波特率计算公式(配套C语言例程)
- android:windowContentOverlay作用
- 260. Single Number III
- 做seo是方案重要还是所谓的技术重要?
- DEDECMS转移数据时提示"dede_advancedsearch' doesn't exist"
- 图论之SPFA
- RocketMQ源码分析(一): 索引文件(IndexFile)
- addEventListener解决多个window.onscroll共存问题
- 多线程是什么?And why linux?
- 小型计算器(JAVA)
- PHP根据自己的经纬度计算5公里范围内的全部经纬度
- Office总是无响应的解决办法
- dedecms模版乱码为什么 织梦cms模版乱码怎么解决方法
- 漫画:什么是HashMap?