spfa(模板)

    spfa作为图论中的常用算法,深受各类出题人和各位OIer的喜爱;

    so,为了给大众创造福利,宝宝在此奉上spfa大发的思路和模板;以感谢社会,

感谢CCF,感谢CCTV,

感谢我的老师,感谢同学们,

感谢noi,感谢noip,感谢ioi,

感谢不辞辛劳的学长学姐,

感谢帮我改程序,被我烦死的xxy ~QAQ~······and so on;

程序和图解做得比较难看,就请大家见谅了!!~(≧▽≦)/~ 谢啦!!☆⌒(*^-゜)v

思路:见程序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int v,x,y,n;
int head[100000],num,m,dis[1000];
bool vis[10000];
struct nond
{
    int pre,v,to,from;
//pre指这条边的上一条边,v指这条边的边权,to指这条边的终点,from至这条边的终点;
}e[100000];//边表存储,减少空间占用;
queue<int>q;//队列存储所能更新的点;
void put(int from,int to,int v)
{
    e[++num].pre=head[from];
    e[num].from=from;//
    e[num].to=to;
    e[num].v=v//;这三句很好理解不解释
    head[from]=num;
}//边表的读入函数;
/*重点解释一下对于改变的上一条边的存储,
看程序下的图片详解,在此不进行解释;*/
void spfa(int s)
{
    q.push(s);//把s放入队列中;
    vis[s]=1;//把节点s标记为使用中;
    int point=s;//用point去更新所有与point相连的节点的最短距离;
    while(!q.empty())//如果队列不为空,说明有节点能去更新其他节点;
    {
        point=q.front();//记录队列中的第一个节点去更行其他节点;
        q.pop();//队列中的第一个节点已被使用,弹出;
        vis[point]=0;//该节点被弹出了队列,变为未被访问,未被使用;
        for(int i=head[point];i;i=e[i].pre)//以该节点去更新其他节点
        {
            if(dis[e[i].from]+e[i].v<dis[e[i].to])//自己理解,不解释
            {
                dis[e[i].to]=dis[e[i].from]+e[i].v;
                q.push(e[i].to);
                //节点i的最短距被更新过,说明i又可以去更新其他节点,把i读入队列;
                vis[e[i].to]=1;//标记为使用中;
            }
        }
    }
}
int main()
{
    cin>>n>>m;//n节点个数,m是边的个数;
    memset(dis,127/3,sizeof(dis));
    dis[1]=0;//dis存储到第i个点的最短路的长度;
    for(int i=1;i<=m;i++){
        cin>>x>>y>>v;//x,y,v分别是相连边的起点~终点~长度;
        put(x,y,v);//向边表里加入边
        put(y,x,v);//因为是无向图,所以加入两次;
    }
    spfa(1);//spfa搜索!!!这是重点!注意了~(≧▽≦)/~
    for(int i=1;i<=n;i++)
    cout<<dis[i]<<" ";
}

如果对你有所帮助,别忘了加好评哦;么么哒!!下次见!88

时间: 2024-10-11 22:56:38

spfa(模板)的相关文章

畅通工程续 (SPFA模板Floy模板)

http://acm.hdu.edu.cn/showproblem.php?pid=1874 SPFA #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 1000001 using namespace std; int n,m; int v[202],dis[202]; struct node { int x,y,z,next; }

SPFA模板 Bellmanford优化版

SPFA模板: queue<int>Q; bool inq[510]; int dis[510],sumv[510]; int n,v[510*3],__next[510*3],e,w[510*3],first[510],cnts[510]; void AddEdge(int U,int V,int W) { v[++e]=V; w[e]=W; __next[e]=first[U]; first[U]=e; } bool spfa(const int &s) { memset(dis,

最短路算法 -- SPFA模板

一.算法步骤 建立一个队列,初始时队列里只有起始点,再建立一个数组记录起始点到所有点的最短路径(该数组的初始值要赋为极大值,该点到它本身的路径赋为0,下面的模板中该数组为dist[]).然后执行松弛操作,用队列里有的点作为起始点去刷新到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后.重复执行直到队列为空. 二.算法模板 1 struct Edge 2 { 3 int s, e, dist; //边的起点.终点.长度 4 5 Edge() {} 6 Edge(int s,

最短路之SPFA模板

一:邻接矩阵版本SPFA//如果要判断负环的话加一个记录入队的数组就行,当入队次数大于n的时候出现负环 int d[MAXN],vis[MAXN],w[MAXN][MAXN]; int n; void SPFA(int s) { fill(d,d+n,INF); d[s]=0; queue<int> q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int v=0; v<n; v++) { if(d[v]>

HDU 1535 &amp;&amp; POJ 1511 Invitation Cards (SPFA 模板 + 反向建图)

Invitation Cards HDU: Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) POJ: Time Limit: 8000 MS     Memory Limit: 262144 K       Problem Description In the age of television, not many people attend theater performa

SPFA模板

Spfa是一种求单源最短路径的算法,时间复杂度为O(每个节点进队次数*边数):(然而对这个复杂度并不是很有概念,比堆优dij是快还是慢啊...) 算法流程: dis数组表示源点s到各点的距离,初始化dis[]={inf}; dis[s]=0; 源点进队: 队首出队: 对队首的每个邻接点做松弛操作: 对于每个被松弛的点,若不在队列中,则加入队列: 重复3~5至队列为空,此时的dis为最短路: STL的queue真是个好东西. 1 void spfa(int k){ 2 int i; 3 memse

SPFA ----模板 O(kE) (k一般不超过2)

原理:若一个点入队的次数超过顶点数V,则存在负环: 1 #include "bits/stdc++.h" 2 3 using namespace std; 4 const int maxN = 200010 ; 5 struct Edge 6 { 7 int to , next , w ; 8 } e[ maxN ]; 9 10 int n,m,cnt,p[ maxN ],Dis[ maxN ]; 11 int In[maxN ]; 12 bool visited[ maxN ]; 1

蓝桥杯训练 最短路 (SPFA模板 vector)

算法训练 最短路 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环).请你计算从1号点到其他点的最短路(顶点从1到n编号). 输入格式 第一行两个整数n, m. 接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边. 输出格式 共n-1行,第i行表示1号点到i+1号点的最短路. 样例输入 3 3 1 2 -1 2 3 -1 3 1 2 样例输出 -1 -2 数据规模与约定 对于10%的数据,n

Dijkstra堆优化与SPFA模板

Dijkstra+优先队列 #include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #include<queue> using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar())