SPFA
来源:互联网 发布:上海徒步俱乐部 知乎 编辑:程序博客网 时间:2024/06/14 09:25
SPFA
单源最短路 ,
可以处理负权边,判断负权环
复杂度 O(K*E),据说K可以证明不会大于2。
hdu 2066
#include <map>#include <set>#include <cmath>#include <queue>#include <string>#include <cstdio>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int N=1005;const int INF=0x3f3f3f3f;#define pb push_back#define fi first#define se second#define mp mak_pair#define pii pair<int,int>struct edge { int v,cost; edge(int _v=0,int _cost=0):v(_v),cost(_cost) {}};vector<edge> es[N];void addEdge(int u,int v,int w) { es[u].pb(edge(v,w));}bool vis[N];int dis[N],cnt[N];//cnt 每个点入队的次数bool SPFA(int s) { memset(cnt,0,sizeof cnt); memset(vis,false,sizeof vis); for(int i=0;i<N;++i) dis[i]=INF; vis[s]=true; dis[s]=0; queue<int> que; que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); int sz=es[u].size(); vis[u]=false; for(int i=0;i<sz;++i) { int v=es[u][i].v; if(dis[u]+es[u][i].cost<dis[v]) { dis[v]=dis[u]+es[u][i].cost; if(vis[v]==false) { vis[v]=true; que.push(v); if(++cnt[v]>n) return false;//存在负权环 } } } } return true;}int st[N],ed[N];int main() { int t,s,d,x,y,c; while(~scanf("%d%d%d",&t,&s,&d)) { for(int i=0;i<N;++i) es[i].clear(); while(t--) { scanf("%d%d%d",&x,&y,&c); addEdge(x,y,c); addEdge(y,x,c); } for(int i=1;i<=s;++i) scanf("%d",&st[i]); for(int i=1;i<=d;++i) scanf("%d",&ed[i]); int ans=INF; for(int i=1;i<=s;++i) { SPFA(st[i]); for(int j=1;j<=d;++j) ans=min(ans,dis[ed[j]]); } printf("%d\n",ans); } return 0;}
邻接表实现
int cnt=0;int last[N];struct edge { int to,pre,cost;}es[2*N];void addEdge(int u,int v,int w) { edge e={v,last[u],w}; es[++cnt]=e; last[u]=cnt;}// last[i] 从i出发的最后一条边的编号// pre 前一条边的编号bool vis[N];int dis[N],cnt[N];//cnt 每个点入队的次数bool SPFA(int s) { memset(cnt,0,sizeof cnt); memset(vis,false,sizeof vis); for(int i=0;i<N;++i) dis[i]=INF; vis[s]=true; dis[s]=0; queue<int> que; que.push(s); while(!que.empty()) { int u=que.front(); que.pop(); vis[u]=false; for(int i=last[u];i!=-1;i=es[i].pre) { int v=es[i].to; if(dis[u]+es[i].cost<dis[v]) { dis[v]=dis[u]+es[i].cost; if(!vis[v]) { vis[v]=true; que.push(v); if(++cnt[v]>n) return false; } } } } return true;}int st[N],ed[N];
邻接表实现方式如下图
last数组存从i出发的最后一条边的编号
pre存上一条边的编号
vis存是否在缓冲队列中
0 0
- SPFA
- spfa
- spfa
- SPFA
- SPFA
- SPFA
- SPFA
- spfa
- SPFA
- SPFA
- SPFA
- SPFA
- SPFA
- spfa
- spfa
- spfa
- SPFA
- SPFA
- 社交课程系列简介
- 2017 年山东省第八届ACM省赛总结
- 量化选股宝三步走,京豆礼包你拿走
- UVa 10817 状压+记忆化搜索
- maven的学习(17.4.25)
- SPFA
- da14580-SUOTA 空中升级
- 给定一个目录,递归的列出下面所有的子目录和文件
- 复习总结《一》MFC消息映射
- HoloLens开发——模型放大缩小复原
- angularjs-$http跨域访问报错的问题
- python数据分析1
- spring-JDBCTemplate配置
- ReentrantLock实现原理深入探究