码迷,mamicode.com
首页 > Web开发 > 详细

复习最短路 spfa+dijstra堆优化

时间:2017-03-07 22:55:20      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:end   push   color   oid   多次   没有   队列   三次   amp   

题目很简单,, 但是wa了三次,, 用<vector>之前一定要记得clear()。。。
简单说下 spfa的问题 和bell_forman有点类似 每次取出一个点 然后更新 并把更新了的节点入队(更新的值可能会影响到最优解) 当队列为空的时候算法结束(无法优化)
这里的vis数组是为了防止重复入队 但每个节点可能多次入队 所以在拿出来的时候 vis标记要消去
最后说下负环的问题 引用一下
对于不存在负权回路的图来说,上述算法是一定会结束的。因为算法在反复优化各个最短路径长度,总有一个时刻会进入“无法再优化”的局面,此时一旦队列读空,算法就结束了。
然而,如果图中存在一条权值为负的回路,就糟糕了,算法会在其上反复运行(因为d[]加上一个负数肯定变下了,所以在有负环的情况下,会不断有数进入队列),通过“绕圈”来
无休止地试图减小某些相关点的最短路径值。假如我们不能保证图中没有负权回路,一种“结束条件”是必要的。这种结束条件是什么呢?
  思考Bellman-Ford算法,它是如何结束的?显然,最朴素的Bellman-Ford算法不管循环过程中发生了什么,一概要循环|V|-1遍才肯结束。凭直觉我们可以感到,SPFA算法
“更聪明一些”,就是说我们可以猜测,假如在SPFA中,一个点进入队列——或者说一个点被处理——超过了|V|次,那么就可以断定图中存在负权回路了。(http://www.cnblogs.com/jiangu66/p/3235361.html)


23号比赛加油~
#include<iostream> #include<vector> #include<queue> #include<cstring> #define E 1001 #define V 101 #define inf 0x3f3f3f3f
using namespace std; struct node { int point,cost; }; vector<node> fuck[V]; int n,m; void dijstra(int s) { int d[V]; priority_queue<int> q; for(int i=1;i<=n;i++) d[i]=inf; d[s]=0; q.push(s); while(!q.empty()) { int now=q.top(); q.pop(); for(int i=0;i<fuck[now].size();i++) { node temp=fuck[now][i]; if(d[temp.point]>d[now]+temp.cost) { q.push(temp.point); d[temp.point]=d[now]+temp.cost; } } } cout<<d[n]<<endl; } // void spfa(int s) { int vis[V]; int d[V],ret[V]; for(int i=1;i<=n;i++) d[i]=inf,vis[i]=ret[i]=0; d[s]=0; queue<int> q; q.push(s); ret[s]++; vis[s]=1; while(!q.empty()) { int now=q.front(); q.pop(); vis[now]=0; for(int i=0;i<fuck[now].size();i++) { node temp=fuck[now][i]; if(d[temp.point]>d[now]+temp.cost) { d[temp.point]=d[now]+temp.cost; if(vis[temp.point]==0) { vis[temp.point]=1; ret[temp.point]++; q.push(temp.point); if(ret[temp.point]>V) { cout<<-1<<endl; return ; } } } } } cout<<d[n]<<endl; } int main() { while(cin>>n>>m) { if(n==0&&m==0) break; for(int i=1;i<=n;i++) fuck[i].clear(); for(int i=1;i<=m;i++) { int x,y,cost; cin>>x>>y>>cost; node temp; temp.cost=cost; temp.point=x; fuck[y].push_back(temp); temp.point=y; fuck[x].push_back(temp); } dijstra(1); //spfa(1); } return 0; }

复习最短路 spfa+dijstra堆优化

标签:end   push   color   oid   多次   没有   队列   三次   amp   

原文地址:http://www.cnblogs.com/z1141000271/p/6517138.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!