题解:P9126 [USACO23FEB] Moo Route II S
hqc20230131 · · 题解
设
这样的 Dijkstra 是不会有负环的,因为
接下来的优化其实比较简单,有贪心的意思。我们把每一个点能够到达的边按照结束时间降序排序,跳过一些走过的边。
最后注意输出 -1 的情况,以及一些优化。
:::success[Dijkstra 的代码]
#include<bits/stdc++.h>
#define N 200005
using namespace std;
struct edge
{
int to,s,t;
bool operator < (const edge &k)const
{
return (s^k.s)?(s>k.s):(t<k.t);
}
};
int n,m,a[N],dis[N],tag[N],inq[N];
vector<edge> g[N];// 注意链式前向星难以对边进行排序,故使用邻接表
void dij()
{
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
for(int i=1;i<=n;i++)dis[i]=tag[i]=1e9+1;
dis[1]=-a[1];// 思考为什么令 dis[1] 为负数
q.push({-a[1],1});
inq[1]=1;
while(!q.empty())
{
int u=q.top().second;
q.pop();
inq[u]=0;
if(tag[u]==dis[u])continue;
tag[u]=dis[u];
for(auto [v,s,t]:g[u])
{
if(s>=dis[u]+a[u]&&dis[v]>t)
{
dis[v]=t;
if(!inq[v])
q.push({dis[v],v}),inq[v]=1;
}
}
}
}
int main()
{
// freopen("sample.in","r",stdin);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1,u,v,s,t;i<=m;i++)
{
cin>>u>>s>>v>>t;
g[u].push_back({v,s,t});
}
for(int i=1;i<=n;i++)sort(g[i].begin(),g[i].end());
for(int i=1;i<=n;i++)cin>>a[i];
dij();
cout<<0<<'\n';
for(int i=2;i<=n;i++)cout<<(dis[i]==1e9+1?-1:dis[i])<<'\n';
return 0;
}
:::