别人的介绍
借用了大佬的思考:
赋所有dis[i]=0,跑最长路,如果某个元素入队次数超过点数就说明有正环。
使用DFS版本的SPFA做比BFS快10倍,为什么?
论文里高大上看不懂,蒟蒻用简单粗暴的方法想了一下:
如果某个环有K个点组成,BFS会从K个点中的某个点开始,每次都换一个点扩展一次,可能达到O(N*K^2)
DFS则只选其中的一个点不断扩展,K次就能使自己重新入队一次,这样就是O(N*K)
孰优孰劣一眼分明
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=3e5+5;
template <typename _Tp> il void read(_Tp&x) {
char ch;bool flag=0;x=0;
while(ch=getchar(),!isdigit(ch)) if(ch=='-')flag=1;
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
if(flag) x=-x;
}
//il int Add(int &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(int &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int T,n,M1,M2;
struct node{int to,w;};
vector<node> G[N];
il void init(){
for(int i=0;i<=n;++i) G[i].clear();
}
il void add(int u,int v,int w){
G[u].push_back({v,w});
}
int ins[N],dis[N],t[N];
il bool ck(){ //判断负环
for(int i=0;i<=n;++i) ins[i]=dis[i]=t[i]=0;
stack<int> stk;
for(int i=0;i<=n;++i){
ins[i]=1,t[i]=1;
stk.push(i);
}
int u;
while(!stk.empty()){
u=stk.top(),stk.pop();
ins[u]=0;
for(auto tp:G[u]){
int to=tp.to,w=tp.w;
if(dis[to]>dis[u]+w){
dis[to]=dis[u]+w;
if(!ins[to]){
stk.push(to);
ins[to]=1,t[to]++;
if(t[to]==n+2) return false; //有负环
}
}
}
}
return true;//无负环
}
int main(){
// std::ios::sync_with_stdio(0);cin.tie(0);
return 0;
}