Spfa
//spfa算的是从x到其他所有点的最短路
QAQ是一种求单源最短路的算法,判断负环非常资磁
用到的变量:
n:点的个数从1到n标号
/*
queue<int>q :一个队列,用stl或者手打,priority_queue也很资磁啊
head:队列头
tail:队列尾
bool vis[Maxm]:判断点是否被遍历过
to[Maxm] :to[i]是记录这条边是到哪个点的
next[Maxm]: next[i]是和i同一个起点出发的下一条边
last[Maxn] :last是记录最后一条边
w[Maxm] :w[i]是边权
*/
vector<int>to[100005],w[100005]:存图用的,to[1][1]=x就是第一个点出去的第一条边到的是X,w[]是边权
模板
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> #define LiangJiaJun main using namespace std; int n,m,st,ed,h[100004],ne,dis[100004]; struct edge{ int to,w,next; }e[500004]; void insert(int u,int v,int w){ e[++ne].to=v; e[ne].next=h[u]; e[ne].w=w; h[u]=ne; } queue<int>q; void spfa(int ask){ memset(dis,127/3,sizeof(dis)); q.push(ask); dis[ask]=0; while(!q.empty()){ int x=q.front();q.pop(); for(int i=h[x];i;i=e[i].next){ if(dis[e[i].to]>dis[x]+e[i].w){ dis[e[i].to]=dis[x]+e[i].w; q.push(e[i].to); } } } } int LiangJiaJun(){ scanf("%d%d%d%d",&n,&m,&st,&ed); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); insert(u,v,w);insert(v,u,w); } spfa(st); printf("%d\n",dis[ed]); return 0; }
#include<algorithm> #include<cstdio> #include<cstring> #include<iostream> #include<queue> #define maxn 500005 using namespace std; bool vis[maxn]; int dis[maxn],h[maxn]; int ecnt=0; int n,m,s; struct data { int to,next,w; }e[maxn]; void ins(int a,int b,int c) { e[++ecnt].to=b; e[ecnt].next=h[a]; h[a]=ecnt; e[ecnt].w=c; } queue<int>q; void spfa(int ask){ q.push(ask); memset(vis,0,sizeof(vis)); memset(dis,127/3,sizeof(dis)); dis[ask]=0; vis[ask]=1; while(!q.empty()) { int x=q.front();q.pop(); vis[x]=0; for(int i=h[x];i;i=e[i].next) { if(dis[e[i].to]>dis[x]+e[i].w) { dis[e[i].to]=dis[x]+e[i].w; if(!vis[e[i].to]) { vis[e[i].to]=1; q.push(e[i].to); } } } } } int main() { cin>>n>>m>>s; for(int a,b,c,i=1;i<=m;++i) { scanf("%d%d%d",&a,&b,&c); ins(a,b,c); } spfa(s); printf("%d",dis[i]); puts(""); return 0; }
模板题
https://www.luogu.org/problem/show?pid=3371
实测比dij快了一倍多
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #define maxn 500005 using namespace std; int n,m,s; int ecnt; int dis[10005]; int h[maxn]; struct node { int to,w,next; }e[maxn]; void ins(int a,int b,int c) { e[++ecnt].to=b; e[ecnt].next=h[a]; h[a]=ecnt; e[ecnt].w=c; } queue <int>q; void spfa(int ask) { memset(dis,0x3f,sizeof(dis)); dis[ask]=0; q.push(ask); while(!q.empty()) { int x=q.front(); q.pop(); for(int i=h[x];i;i=e[i].next) { if(dis[e[i].to]>dis[x]+e[i].w) { dis[e[i].to]=dis[x]+e[i].w; q.push(e[i].to); } } } } int main() { cin>>n>>m>>s; int a,b,c; for(int i=1;i<=m;++i) { scanf("%d%d%d",&a,&b,&c); ins(a,b,c); } spfa(s); for (int k = 1; k <= n; k++) { printf("%d ", dis[k] == 0x3f3f3f3f ? 2147483647 : dis[k]); } return 0; }