洛谷P3385 负环与SPFA算法

SPFA算法:

SPFA算法是图论中主要应用于解决带负权图相关问题的一种算法,它死了。

时间复杂度:O(ke)//k为平均每个节点入队次数

算法思路

1,建立先进先出队列存放待优化结点;

2,每次去除当前队首结点u,用u最短路径估计值将与u相连的结点v进行松弛操作,若v最短路径被更新且v不在队列中,将v加入队尾;

 (松弛操作:对,每个集合中的节点v,都设置dis[v]表示起点与v间最短路径权值的上界的操作

3,重复上述操作直至队列为空。

于是板子题又双叒叕应运而生:https://www.luogu.com.cn/problem/P3385

复制代码
 1 #include<bits/stdc++.h>
 2 #define ff(i,s,e) for(int i=s;i<=e;i++)
 3 #define fff(i,s,e) for(int i=s;i>=e;i--)
 4 using namespace std;
 5 inline int read(){
 6     int x=0,f=1;
 7     char ch=getchar();
 8     while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
 9     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
10     return x*f;
11 }
12 const int N=2010,M=3010,inf=0x3f3f3f3f;
13 int n,m;
14 int tal,head[N];
15 int dis[N];
16 int mark[N];//元素i被标记过几次 
17 bool vis[N];//元素i是否在队列中 
18 struct qwq{
19     int to,nxt,w;
20 }a[M*2];
21 queue<int> q;
22 void add(int u,int v,int w){//链式前向星存储 
23     a[++tal].w=w;
24     a[tal].to=v;
25     a[tal].nxt=head[u];
26     head[u]=tal;
27 }
28 bool spf(){
29     ff(i,1,n) dis[i]=inf,vis[i]=0,mark[i]=0;//预处理 
30     while(!q.empty()) q.pop();//清空队列 
31     q.push(1);//将起点加入队列 
32     dis[1]=0,vis[1]=1,mark[1]++;
33     while(!q.empty()){
34         int u=q.front();//取出队首元素 
35         q.pop();
36         vis[u]=0;//标记队首出队 
37         for(int i=head[u];i;i=a[i].nxt){//枚举u可到达的所有结点 
38             int v=a[i].to;
39             if(dis[v]>dis[u]+a[i].w){//若以u为中转结点更优,更新
40                 dis[v]=dis[u]+a[i].w; 
41                 if(!vis[v]){//若v不在队列,将其加入 
42                     vis[v]=1,mark[v]++;q.push(v);
43                 }
44                 if(mark[v]>=n) return 1;//判断负环,可由松弛原理推导 
45             }
46         }
47     }
48     return 0;
49 }
50 int main(){
51     int T=read(),u,v,w;
52     while(T--){
53         n=read(),m=read();
54         tal=0; 
55         memset(head,0,sizeof(head));//初始化 
56         ff(i,1,m){
57             u=read(),v=read(),w=read();
58             add(u,v,w);
59             if(w>=0) add(v,u,w);
60         }
61         if(spf()) printf("YES\n");
62         else printf("NO\n");
63     }
64     return 0;
65 }
复制代码

阿巴阿巴

posted @   专吃小仙女  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示