图算法--判负环

bellman-ford判负环,据bellman-ford的性质最后得出的是通过不超过n-1条边的从起点到其他点的最短距离(因为n个点,所以n-1条边)

但是如果在n-1次循环之后仍然存在边可以被松弛,那么就存在负环(因为如果没有负环n-1次就已经确定了最短距离,具体可参考bellman-ford证明,已经是最短距离了还能被松弛,必然是存在负环)

复制代码
 1 #include<iostream>
 2 using namespace std;
 3 const int N=2010,M=1e5+10;
 4 int n,m;
 5 struct edge{
 6     int a,b,w;
 7 }edges[M];
 8 int dis[N];
 9 void bellman_ford(){
10     //直接把dis初始化为全0就可以了,意思就是所有的点都是起点
11     for(int i=0;i<n-1;i++){
12         for(int j=0;j<m;j++){
13             auto t=edges[j];
14             if(dis[t.b]>dis[t.a]+t.w){
15                 dis[t.b]=dis[t.a]+t.w;
16             }
17         }
18     }
19 }
20 int main(void){
21     cin>>n>>m;
22     for(int i=0;i<m;i++){
23         int a,b,c;
24         cin>>a>>b>>c;
25         edges[i]={a,b,c};
26     }
27     bellman_ford();
28     for(int j=0;j<m;j++){
29             auto t=edges[j];
30             if(dis[t.b]>dis[t.a]+t.w){
31                 cout<<"Yes";
32                 return 0;
33             }
34     }
35     cout<<"No";
36     return 0;
37 }
复制代码

spfa判负环

复制代码
 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=2010,M=1e5+10;
 6 int n,m;
 7 int h[N],e[M],w[M],ne[M],idx;
 8 int dis[N],cnt[N];
 9 bool st[N];
10 void add(int a,int b,int c){
11     e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
12 }
13 bool spfa(){
14     queue<int> q;
15     for(int i=1;i<=n;i++){
16         q.push(i);
17         st[i]=true;
18     }//把所有的点都丢进队列里面
19     while(q.size()){
20         int t=q.front();
21         q.pop();
22         st[t]=false;
23         for(int i=h[t];i!=-1;i=ne[i]){
24             int j=e[i];
25             if(dis[j]>dis[t]+w[i]){
26                 dis[j]=dis[t]+w[i];
27                 cnt[j]=cnt[t]+1;
28                 if(cnt[j]>=n){
29                     return true;
30                 }
31                 if(!st[j]){
32                     q.push(j);
33                     st[j]=true;
34                 }
35             }
36         }
37     }
38     return false;
39 }
40 int main(void){
41     cin>>n>>m;
42     memset(h,-1,sizeof(h));
43     for(int i=0;i<m;i++){
44         int a,b,c;
45         cin>>a>>b>>c;
46         add(a,b,c);
47     }
48     if(spfa()){
49         cout<<"Yes";
50     }else{
51         cout<<"No";
52     }
53     return 0;
54 }
复制代码

 

posted on   greenofyu  阅读(198)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示