首先看到这道题目,我们发现这道题目的复杂度,首先确定了是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
时间: 2024-10-13 08:59:26