別人的介紹
借用了大佬的思考:
賦所有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;
}