• SSLZYC 【模板】单源最短路径 【SPFA】


    题目大意:
    求出一个点到其他所有点的最短路径。

    Input

    4 6 1
    1 2 2
    2 3 2
    2 4 1
    1 3 5
    3 4 3
    1 4 4

    Output

    0 2 4 3

    思路:

    最短路

    思路一:dijkstra

    当时还没有学SPFA,看了数据感觉dijkstra可以卡过,于是打了一发dijkstra,结果
    这里写图片描述
    也许是我打错了,可能可以得70分。请dalao指教。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    const int inf=99999999;
    using namespace std;
    
    int n,m,k,a[10001][10001],b[10001],c[10001],minn,o,x,y;
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            scanf("%d",&a[x][y]);  //存入有向边
        }
        b[k]=1;
        a[k][k]=0;
        for (int i=1;i<=n;i++)
         if (a[i][k]>0) c[i]=a[i][k];
          else c[i]=inf;
        c[k]=0;
        for (int j=1;j<=n-1;j++)
        {
            minn=inf-1;
            for (int i=1;i<=n;i++)
             if (b[i]==0&&c[i]<minn)  //找最短边
             {
                minn=c[i];
                o=i;
             }
            b[o]=1;  //访问
            for (int i=1;i<=n;i++)
             if (b[i]==0&&c[i]>a[o][i]+c[o]) c[i]=c[o]+a[o][i];   //更新最短路
        }
        for (int i=1;i<=n;i++)
         if (c[i]!=inf) printf("%d ",c[i]);
         else printf("2147483647 ");
        return 0;
    }
    
    思路二:SPFA

    这道题的正解就是SPFA。首先用邻接表储存边(用邻接矩阵会MLE,而且那还叫什么SPFA),然后利用模板库queue构造队列,利用邻接表加速,依次访问每个点,更新最短路,最终输出加一个判断就可以了。

    #include <iostream>
    #include <cstdio>
    #include <queue>
    using namespace std;
    
    const int inf=99999999;
    int n,m,s,t,k,head[30001],dis[30001],vis[30001],x,y,Dis;
    
    struct edge  //邻接表
    {
        int to,dis,next;
    }e[1500001];
    
    void add(int from,int to,int Dis)  //建图
    {
        k++;
        e[k].next=head[from];
        e[k].to=to;
        e[k].dis=Dis;
        head[from]=k;
    }
    
    void spfa()
    {
        queue<int> q;  //队列
        for (int i=1;i<=n;i++)  //初始化
        {
            dis[i]=inf;
            vis[i]=0;
        }
        q.push(s);  //加入出发点
        vis[s]=1;
        dis[s]=0;
        while (q.size())  //相当于 while(!q.empty())
        {
            int u=q.front();  //取出队首
            q.pop();  //弹出
            vis[u]=0;  //访问标记
            for (int i=head[u];i;i=e[i].next)  //邻接表加速
            {
                int v=e[i].to;  //到达点
                if (dis[v]>dis[u]+e[i].dis)  //更新最短路
                {
                    dis[v]=dis[u]+e[i].dis;
                    if (!vis[v])  //访问标记
                    {
                        vis[v]=1;
                        q.push(v);  //入队
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&s);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&Dis);
            add(x,y,Dis);  //建图
        }
        spfa();
        for (int i=1;i<=n;i++)
         dis[i]==inf?printf("2147483647 "):printf("%d ",dis[i]);  //相当于 if (dis[i]!=inf) printf("%d ",dis[i]); else printf("2147483647 ");
        return 0;
    }
  • 相关阅读:
    centos shell运行报语法错误: 未预期的文件结尾
    腾讯云防暴力破解防异地登陆
    centos常用命令
    centos7安装nginx
    JavaScript数组倒序函数reverse()
    Ecshop首页购物车数量调取问题
    (原)IPhone开发时把ToolBar中的元素居中的技巧
    iphone开发常用代码笔记
    Windows环境下使用Apache+mod
    [转]C++中sizeof(struct)怎么计算?
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313054.html
Copyright © 2020-2023  润新知