ACM_SPFA算法
来源:互联网 发布:全国软件测试大赛 编辑:程序博客网 时间:2024/06/03 21:03
SPFA算法:首先源点到源点的距离为0,然后用源点对其他点进行松弛操作(更新操作),若松弛成功,表明源点到其的路径变小了,那么该点有可能能作为中间点松弛其他点,所以得将其入队列(如果它不在队列里面的话)某个点得到了松弛,如果它在队列里面,那么它能松弛的点会在接下的过程中得到松弛,如果它在这之前已经松弛了其他点,那么由于它受到了松弛,则那些它可以松弛的点将会进一步被松弛,所以它得重新入队列;如果没有负权值的边,那么松弛操作不会一直下去,当队列里的元素为空时,算法结束!
#include<cstdio>#include<iostream>#include<queue>#include<cstring>using namespace std;#define len 100#define INF 9999999int n,m,s,d,dis[len],vis[len],road[len][len],cot[len];//n个点,m条边,s源点,d终点;dis[i]->s到i的最短距离,//vis[i]判断i是否在队列中,road数组存图,cot[i]表示i进//队列的次数,也就是i更新dis数组的次数bool spfa(){ int i,t;; for (i = 1; i <= n; ++i) dis[i] = INF;//初始时,源点到其他点的距离为无穷大 memset(vis,0,sizeof(vis)); memset(cot,0,sizeof(cot)); queue<int>q; q.push(s); dis[s] = 0; vis[s] = 1; while (!q.empty()) { t = q.front(); q.pop(); vis[t] = 0; ++cot[t]; if (cot[t] > n) return false; for (i = 1; i <= n; ++i) { if (dis[i] > dis[t] + road[t][i])/*假设1,2之间存在负权值的边,如果1(或2)为源点,那么当i=2时,dis[2]更新(无穷大->负值),2入队列;当2出队列,i=1时,dis[1]被更新(0->负值),1入队列,2被更新......那么对列将不会为空*/ { dis[i] = dis[t] + road[t][i]; if (!vis[i]) { q.push(i); vis[i] = 1; } } } } return true;}int main(){ int i,j,u,v,w; while (cin>>n>>m) { for (i = 1; i <= n; ++i) { for (j = 1; j <= n; ++j) road[i][j] = i == j ? 0 : INF; } for (i = 1; i <= m; ++i) { scanf("%d%d%d",&u,&v,&w); road[u][v] = road[v][u] = w; } scanf("%d%d",&s,&d); if (spfa()) { cout<<dis[d]<<endl; } else cout<<"sorry"<<endl; } return 0;}
0 0
- ACM_SPFA算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 算法
- 用标签遍历双层的list
- iOS 开发:设计模式
- xcode 6 新建pch文件
- 阐述H264裸流与TS流之间的关系(一)
- xcode7禁用了明文http传输的解决方法
- ACM_SPFA算法
- SpringMVC注解...@controller和@RequestMapping
- JavaScript学习要点(四)
- jquery选择器汇总
- JNIEnv解析
- 2012年5月SAT香港真题解析
- poj 3280 区间dp
- jstring 和string char*之间的转换
- 给还在上学的你们