• 道路与航线(双端队列deque优化的SPFA)


     思路:首先有负权值,考虑SPFA,但是数据范围所以就得用双端优化过的SPFA。

    #include<bits/stdc++.h>
    #include<cstring>
    #include<string.h>
    #include<cstdio>
    using namespace std;
    typedef long long ll ;
    const int N=1e5+10;
    int  dis[N];
    int tg=0x3f3f3f3f;
    int t,r,p,s;
    bool vis1[N];
    struct node
    {
        int to;
        int w;
    };
    vector<node> vec[N];
    void spfa(){
        memset(vis1,0,sizeof(vis1));
        deque<int>q;
        q.push_back(s);
        dis[s]=0;
        vis1[s]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop_front();
            vis1[u]=0;
            for(int i=0; i<vec[u].size(); i++)
            {
                int to=vec[u][i].to;
                int w=vec[u][i].w;
                if(dis[to]>dis[u]+w){
                    dis[to]=dis[u]+w;
                    if(!vis1[to])
                    {
                        int tp=q.front();
                        if(!q.empty()&&dis[tp]>dis[to])
                            /*
                            如果当前点到起始点的距离小于队头的tp到起始点的距离就把当前点放在队头*/
                            q.push_front(to);
                        else
                            q.push_back(to);
                        /*
                            如果当前点到起始点的距离大于队头的tp到起始点的距离就把当前点放在队尾*/
                        vis1[to]=1;
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d%d%d",&t,&r,&p,&s);
        //n=s;
        int x,y,w;
        for(int i=1; i<=r; i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            vec[x].push_back({y,w}),
            vec[y].push_back({x,w});
        }
        for(int i=1; i<=p; i++)
        {
            scanf("%d%d%d",&x,&y,&w);
            vec[x].push_back({y,w});
        }
          for(int i=0;i<N;i++)
                dis[i]=tg;  //不要用memset!!!,不然判断是否存在的时候会存在一些不可思议的事情。
        spfa();
        for(int i=1; i<=t; i++)
        {
            if(dis[i]==tg)
                cout<<"NO PATH"<<endl;
            else
                cout<<dis[i]<<endl;
    
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    util包的常用类及其方法(下)
    util包的常用类及其方法(上)
    每日一记--java基础01
    每日一记--java细节之问01
    每日一记--设计模式01
    每日一记--JVM虚拟机01
    每日一记--java基础之final/static/事务
    每日一记--Mysql错误代码1067
    每日一记--AOP
    每日一记--代理模式
  • 原文地址:https://www.cnblogs.com/sszywq/p/13960556.html
Copyright © 2020-2023  润新知