spfa判负环
bfs版spfa
void spfa(){ queue<int> q; for(int i=1;i<=n;i++) dis[i]=inf; q.push(1);dis[1]=0;vis[1]=1; while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; if(!vis[v]){ vis[v]=1;q.push(v); } } } } }
dfs无优化版spfa
void spfa(int u){ instack[u]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; if(!instack[v]) spfa(v); else return; } } instack[u]=0; }
dfs版spfa判断环
bool spfa(int u){ vis[u]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[u]+w<dis[v]){ dis[v]=dis[u]+w; if(vis[v]||!spfa(v)) return 0;} }vis[u]=0;return 1; }
spfa判负环:luogu 3385
p.s:其实此题也是要先判连通性的,数据水过
1.bfs无优化版 O(n*m) 40
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=2005; const int M=3005; int n,m,u,v,w,t; int cnt[N],vis[N],head[N],dis[N],tot; struct node{int v,w,next;}e[M]; void insert(int u,int v,int w){ e[++tot]=(node){v,w,head[u]};head[u]=tot;} int spfa(){ queue<int> q; memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); dis[1]=0;vis[0]=1;q.push(1); while(!q.empty()){ int u=q.front();q.pop();cnt[u]++; if(cnt[u]>n) return 1; if(dis[u]==inf) continue; for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[u]+w<dis[v]){ dis[v]=dis[u]+w; vis[v]=1; q.push(v); } }vis[u]=0; } return 0; } int main(){ cin>>t; while(t--){ memset(head,0,sizeof head); memset(e,0,sizeof e); tot=0; cin>>n>>m; for(int i=1;i<=m;i++){ cin>>u>>v>>w; insert(u,v,w); if(w>=0) insert(v,u,w);} if(spfa()) printf("YE5\n"); else printf("N0\n"); } return 0; }
2.bfs优化版(虽然思路清奇但是能AC就行)
更新p.s: 1.没有判连通性 2.无法处理有负边无负环的情况,cnt[v]=cnt[u]+1,并不通用
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define dec(i,x,y) for(register int i=x;i>=y;i--)
#define ll long long
using namespace std;
const int N=20005;
const int M=100010;
const int inf=0x3f3f3f3f;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}int n,m;
int vis[N],dis[N],cnt[N],s=1;
int head[N],tot;
struct node{int v,w,next;}e[M];
void insert(int u,int v,int w){
e[++tot]=(node){v,w,head[u]};head[u]=tot;}
inline int spfa(){
queue<int> q;
memset(dis,inf,sizeof dis);
memset(vis,0,sizeof vis);
memset(cnt,0,sizeof cnt);
dis[s]=0;vis[s]=1;cnt[s]=1;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v,w=e[i].w;
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
if(!vis[v]){
cnt[v]=cnt[u]+1;
if(cnt[v]>=n) return 1;
vis[v]=1,q.push(v);
}
}
}
}return 0;
}
int main(){
int t=read();
while(t--){
n=read();m=read();
memset(head,0,sizeof head);
tot=0;
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
insert(u,v,w);
if(w>=0) insert(v,u,w);
}if(spfa()) printf("YE5\n");
else printf("N0\n");
}return 0;
}
3.dfs版,dis置0 0
#include<bits/stdc++.h> using namespace std; const int N=210005; int t,n,m,cnt,dis[N],vis[N],head[N],fg; struct node{int v,w,next;}e[N<<1]; inline void insert(int u,int v,int w){ e[++cnt]=(node){v,w,head[u]};head[u]=cnt;} void spfa(int u){ vis[u]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[v]>dis[u]+w){ if(vis[v]||fg){fg=1;break;} dis[v]=dis[u]+w; spfa(v); } }vis[u]=0; }int a,b,w; int main(){ cin>>t; while(t--){ memset(dis,0,sizeof dis);//dis置0 memset(vis,0,sizeof vis); memset(head,0,sizeof head); memset(e,0,sizeof e); cnt=0; cin>>n>>m; for(int i=1;i<=m;i++){ cin>>a>>b>>w; insert(a,b,w); if(w>=0) insert(b,a,w); }fg=0; for(int i=1;i<=n;i++){ spfa(i);if(fg)break;} if(fg) printf("YE5"); else printf("N0"); }return 0; }
4.dfs简单版
#include<bits/stdc++.h> #define il inline #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) using namespace std; const int N=50005,inf=23333333; int n,m,to[N],net[N],w[N],dis[N],cnt,h[N],tot[N]; bool vis[N]; il int gi(){ int a=0;char x=getchar(); while(x<'0'||x>'9')x=getchar(); while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar(); return a; } il void add(int u,int v,int c){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,w[cnt]=c;} il bool spfa(int u){ vis[u]=1; for(int i=h[u];i;i=net[i]) if(dis[to[i]]<dis[u]+w[i]){ dis[to[i]]=dis[u]+w[i]; if(vis[to[i]])return 0; if(!spfa(to[i]))return 0; } vis[u]=0; return 1; } int main(){ n=gi(),m=gi(); int f,a,b,c; while(m--){ f=gi(),a=gi(),b=gi(); if(f==1)c=gi(),add(b,a,c); else if(f==2)c=gi(),add(a,b,-c); else if(f==3)add(a,b,0),add(b,a,0); } For(i,1,n)add(0,i,0),dis[i]=-inf; if(!spfa(0))cout<<"No"; else cout<<"Yes"; return 0; }