zoukankan      html  css  js  c++  java
  • POJ 1511 最短路spfa

    题很简单 就是有向图中求给出的源点到其余所有点的最短路的和与其余所有点到源点的最短路之和

    一开始以为dij对于正权图的单源最短路是最快的 写了一发邻接表的dij 结果超时 把所有的cin改成scanf 还是超时(过去并没有用cin的坏习惯..近两个星期才开始疯狂的使用cin..因为懒..)

    后来想了一下 spfa也可以求单源最短路 就试着写了一发scanf 然后wa...看了半天题目 发现是有很大可能爆int的 改了后1800+msAC 用cin仍然超时

    所以cin害人不浅 scanf大法好23333333

    咨询了一下学长 学长给出来一个看似很有道理的解答:dij与bel都是直接在所有直接相连的点或者是所有直接相连的边里选最优 spfa是bell的优化 所以一定程度上也是对dij的优化 spfa讲道理是可以适合两个版本的

    自己思考了一下 dij是耿直的尝试更新 spfa是如果可以松弛就放入队列 于是同一个点避开了多次的尝试作为终点更新 大概是这样吧...稀疏图应该是dij更快把..

    至于为什么不写堆优化的dij呢?当然是我不会了23333333333333333333333

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<math.h>
    #include<queue>
    #include<iostream>
    using namespace std;
    int n,m;
    int t1,t2;
    struct node
    {
        int v;
        long long  w;
        int nex;
    };
    node a[1000050];
    node b[1000050];
    int p1[1000050];
    int p2[1000050];
    void add1(int u,int v,long long  w)  /// real
    {
        a[t1].v=v;
        a[t1].w=w;
        a[t1].nex=p1[u];
        p1[u]=t1;
        t1++;
    }
    void add2(int u,int v,long long  w)  /// un
    {
        b[t2].v=v;
        b[t2].w=w;
        b[t2].nex=p2[u];
        p2[u]=t2;
        t2++;
    }
    long long  dis1[1000050];
    long long  dis2[1000050];
    bool vis[1000050];
    void spfa1(){
    queue<int >q;
    q.push(1);
    vis[1]=false;
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=true;
        for(int tt=p1[u];tt!=-1;tt=a[tt].nex)
        {
            int v=a[tt].v;
            int w=a[tt].w;
            if(dis1[u]+w<dis1[v])
            {
                dis1[v]=dis1[u]+w;
                if(vis[v])
                {
                    vis[v]=false;
                    q.push(v);
                }
            }
        }
    }
    }
    void spfa2(){
    queue<int >q;
    q.push(1);
    vis[1]=false;
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=true;
        for(int tt=p2[u];tt!=-1;tt=b[tt].nex)
        {
            int v=b[tt].v;
            int w=b[tt].w;
            if(dis2[u]+w<dis2[v])
            {
                dis2[v]=dis2[u]+w;
                if(vis[v])
                {
                    vis[v]=false;
                    q.push(v);
                }
            }
        }
    }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
                dis1[i]=dis2[i]=999999999999999;
            dis1[1]=0;
            dis2[1]=0;
            for(int i=1; i<=n; i++)
                vis[i]=true;
            for(int i=1; i<=n; i++)
            {
                p1[i]=p2[i]=-1;
            }
            t1=t2=0;
            for(int i=1; i<=m; i++)
            {
                int u,v;
                long long w;
                scanf("%d%d%I64d",&u,&v,&w);
                add1(u,v,w);
                add2(v,u,w);
            }
            spfa1();
            for(int i=1; i<=n; i++)
            vis[i]=true;
            spfa2();
            long long  ans=0;
            for(int i=2;i<=n;i++)
            {
                ans+=dis1[i];
                ans+=dis2[i];
            }
            printf("%I64d
    ",ans);
        }
    }
    

      

  • 相关阅读:
    【最短路】The 2019 Asia Nanchang First Round Online Programming Contest Fire-Fighting Hero (Dijkstra)
    【积累】The 2019 Asia Nanchang First Round Online Programming Contest The Nth Item (矩阵快速幂 k进制快速幂)
    【线段树】The Preliminary Contest for ICPC Asia Xuzhou 2019 Colorful String(回文树+线段树+状压/bitset)
    allure参数说明及代码示例
    Idea+maven+testng+reportng生成测试报告
    ubuntu 16.04 镜像下载
    new AndroidDriver报错java.lang.NoSuchMethodError: com.google.common.base.Throwables.throwIfUnchecked
    Appium常用的API
    Appium常用的定位方法
    adb 指令总结
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/5550849.html
Copyright © 2011-2022 走看看