ACwing 342. 道路与航线

首先看到这道题目,我们发现这道题目的复杂度,首先确定了是O(nlogn)O(nlogn)级别的,所以说,我们的算法初步确定在dijskra和SPFA上面.

但是我们发现这道题目一个关键点,就是题目中出现了负权边.

一旦出现了负权边,那么我们只能使用SPFA。

关于SPFA优化https://www.cnblogs.com/TFLS-gzr/p/10389141.html

#include <bits/stdc++.h>
using namespace std;
const int N=400000 +100;
int head[N],ver[N],Next[N],edge[N],vis[N],dis[N],tot;
void add_edge(int a,int b,int c)
{
    edge[tot]=b;
    ver[tot]=c;
    Next[tot]=head[a];
    head[a]=tot++;
}
void spfa(int s)
{
    memset(dis,0x3f,sizeof(dis));
    memset(vis,false,sizeof(vis));
    deque<int> q;
    dis[s]=0;
    vis[s]=true;
    q.push_back(s);
    while(q.size())
    {
        int now=q.front();
        vis[now]=false;
        q.pop_front();
        for(int i=head[now]; ~i; i=Next[i])
        {
            int j=edge[i];
            if (dis[j]>dis[now]+ver[i])
            {
                dis[j]=dis[now]+ver[i];
                if (!vis[j])
                {
                    vis[j]=true;
                    if (q.size() && dis[j]<dis[q.front()])
                        q.push_front(j);
                    else
                        q.push_back(j);
                }
            }
        }
    }
}
int main()
{
    int t,r,p,s,x,y,z;
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t>>r>>p>>s;
    memset(head,-1,sizeof(head));
    for(int i=1; i<=r; i++)
    {
        cin>>x>>y>>z;
        add_edge(x,y,z);
        add_edge(y,x,z);
    }
    for(int i=1; i<=p; i++)
    {
        cin>>x>>y>>z;
        add_edge(x,y,z);
    }
    spfa(s);
    for(int i=1; i<=t; i++)
    {
        if (dis[i]==0x3f3f3f3f)
            cout<<"NO PATH"<<endl;
        else
            cout<<dis[i]<<endl;
    }
    return 0;

  

  

原文地址:https://www.cnblogs.com/ruanmowen/p/12708306.html