zoukankan      html  css  js  c++  java
  • 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

    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    19_05_01校内训练[划分]
    19_05_01校内训练[polygon]
    [Untiy]贪吃蛇大作战(四)——游戏主界面
    [Untiy]贪吃蛇大作战(三)——商店界面
    [Untiy]贪吃蛇大作战(二)——规则界面
    [Untiy]贪吃蛇大作战(一)——开始界面
    [C#]简单的理解委托和事件
    [C#]关于override和new在重写方法时的区别
    [C#]关于逆变与协变的基本概念和修饰符in与out的意义
    [剑指Offer]剪绳子
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/6193850.html
Copyright © 2011-2022 走看看