我对本题目的多篇题解的SPFA进行了双端队列优化, 网络上没有SLF判断负环的正解。 其中判断入队次数的优化后WA#9line2, 且与其他算法(floyd)的答案不符。 判断dep的重复多次入队导致TLE, 但是我不明白为什么会出现在没有负环的情况下重复入队且不计次数。 以下是我修改后的一份题解代码。
#include<bits/stdc++.h>
const int maxn=2e3+10;
const int maxm=6e3+10;
int n,m;
struct Edge{
int to,w,next;
}edge[maxm];
int head[maxn],tot;
inline void Init(){
for(int i=0;i<maxm;i++) edge[i].next=0;
for(int i=0;i<maxn;i++) head[i]=0;
tot=0;
}
inline void addedge(int u,int v,int w){
edge[++tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot;
}
using std::deque;
deque<int> Q;
int dis[maxn],vis[maxn],cnt[maxn];
bool spfa(){
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
dis[1]=0; vis[1]=true;
Q.push_back(1);
while(!Q.empty()){
int x=Q.front();
Q.pop_front();
vis[x]=false;
for(int i=head[x];i;i=edge[i].next){
int y=edge[i].to,z=edge[i].w;
if(dis[y]>dis[x]+z){
dis[y]=dis[x]+z;
cnt[y]=cnt[x]+1;
if(cnt[y]>=n) return true;
if(!vis[y]){
if(Q.empty())
Q.push_back(y);
else if(dis[Q.front()]<dis[y])
Q.push_back(y);
else
Q.push_front(y);//修改部分
vis[y]=true;
}
}
}
}
return false;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
Init();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
if(w>=0) addedge(v,u,w);
}
puts(spfa()?"YES":"NO");
}
return 0;
}
谢谢。