道路与航线(双端队列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

 

posted @ 2020-11-11 19:46  Swelsh-corgi  阅读(153)  评论(0编辑  收藏  举报