• 1511 基础spfa


    题意,求0点到N-1点的来回最短路。

    这题是基础spfa题:

    坑爹的用了一个下午的时间弄,这题的输入居然要用scanf,为啥没hit提示呢,以后遇到TLE就要考虑是否输入的问题了。

    总结下spfa算法,比较高效的算法,有点繁琐,主要是利用了邻接表和队列的形式,与bfs很像。

    同时可以利用入队次数到达V判断是否有负环。

    spfa优化算法在这题用不着。。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int  maxn=0x3f3f3f3f;
    const int  N=1000005;
    const int  E=1000005;
    
    struct Edge{
        int pnt;
        int dis;
        int next;
    }edge1[E],edge2[E];
    int n,e,cur,aver;
    int neigh1[N],neigh2[N];
    int que[N],mindis[N],front,rear;
    bool vis[N];
    
    void spfa(int s,int v)
    {
        Edge *edge;
        int *neigh;
        if(v==1)
        {
            edge=edge1;
            neigh=neigh1;
        }
        else
        {
            edge=edge2;
            neigh=neigh2;
        }
    
        for(int i=0;i<n;i++)
        {
            mindis[i]=maxn;
            vis[i]=false;
        }
        int averge=aver/cur;
        int num=cur;
        front=rear=0;       //s入队
        mindis[s]=0;
        que[rear++]=s;
        while(front!=rear)
        {
            int pre=que[front];
            vis[pre]=false;
            int t=neigh[pre];
    
            while(t!=-1)
            {
               int pnt= edge[t].pnt;
               if(mindis[pnt]>mindis[pre]+edge[t].dis)
                  {
                    mindis[pnt]=mindis[pre]+edge[t].dis;
                    if(!vis[pnt])
                    {
                        vis[pnt]=true;
                        que[rear++]=pnt;
    
                        if(mindis[que[rear-1]]<mindis[que[front]])//SLF优化算法
                        swap(que[rear-1],que[front]);
                        if(rear==N) rear=0;
                    }
                  }
                t=edge[t].next;
            }
            if(++front==N)  {front=0;}
        }
    }
    int main()
    {
        int T,begin,end,dis;
        long long sum;
        scanf("%d", &T);
        while(T--)
        {
            cur=0;
            aver=0;
            scanf("%d%d", &n, &e);
            for(int i =0;i<n;i++)neigh1[i]=neigh2[i]=-1;
            for(int i =0;i<e;i++)
            {
                scanf("%d%d%d", &begin, &end, &dis);
                begin--;
                end--;
                aver+=dis;
                edge1[cur].pnt=end;
                edge1[cur].dis=dis;
                edge1[cur].next=neigh1[begin];
                neigh1[begin]=cur;
                edge2[cur].pnt=begin;
                edge2[cur].dis=dis;
                edge2[cur].next=neigh2[end];
                neigh2[end]=cur;
                cur++;
            }
    
            sum=0;
            spfa(0,1);
            for(int i=1;i<n;i++)sum+=mindis[i];
            spfa(0,2);
            for(int i=1;i<n;i++)sum+=mindis[i];
            printf("%lld\n", sum);
        }
        return 0;
    }
    


     

  • 相关阅读:
    Gmail邮件被屏蔽
    每天读两本书的方法
    如何做到一天读一本书?
    给网站加图标
    接口和类的异同
    生气的时候如何不生气
    只有某行文字间距较大
    视频流媒体监控系统EasyDSS是如何在无人机巡查秸秆焚烧中发挥作用的?
    互联网直播点播平台EasyDSS视频直播通道被占用了怎么处理?
    互联网直播点播平台EasyDSS如何实现电梯监控?EasyDSS电梯云物联解决方案介绍
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134223.html
Copyright © 2020-2023  润新知