求负环-基于SPFA算法

在这里插入图片描述
一般情况下,我们用第二种。
在第一种中,如果有一个点入队n次,代表这个点被更新了n次。
负环: 一个有向图/无向图中 环路的边权和<0
因为是一个环,所以可以循环无限次,那么这些环上的点的距离就会变成-∞

求负环:
基于spfa
spfa 每入队一次 就相当于更新一次 如果入队>=n次
在bellman_ford中 每更新一次 最短距离变小 但一个点的最短距离不可能变小n次
1 统计每个点入队的次数 如果某个点入队n次
说明存在负环
←o
↓ ↑
o→o→o…o→o 总共n个点,则对于点i到其他点最多n-1条边,入队n次说明包含n条让dist[i]变小的边
同时因为更新原则是加上第n条边后最短路权重变小
所以第n条边是负的 则该路径一定存在负环
2 统计当前每个点的最短路中所包含的边数,如果某个点的最短路所包含的边数>=n
说明存在负环

n条边 则一定有n+1个点 但我们总共就n个点 所以这条最短路上一定有环
同时因为更新原则是加上第n条边后最短路权重变小
所以第n条边是负的 则该路径一定存在负环

推荐第2种方法:
考虑:
当数据如 -1
o←o
-1↓ ↑-1
o→o
-1
如果用第一种方法 转完一圈之后每个点只入队一次,达到判定要求则需要转n圈
O(n^2)
如果用第二种方法 转完一圈之后就能达到判定要求
O(n)

还有一个问题:
负环不一定从起点走到

4
↓ ↑
1→…2→3
解决方案:
将所有点入队的同时把所有点的距离初始化为0
q.push(node) for all_node
dist[node] = 0 for all_node
why 所有点入队? (结合虚拟源点建新图理解)
1 虚拟源点0向所有点连一条长度是0的边构成一条新的图
同时以虚拟源点0作为新图的起点
2 原图中存在负环 == 新图中存在负环
而新图里所有的负环一定能从虚拟源点出发走到
3 那么我们对新图做spfa时就是把虚拟源点0加入queue
而0 pop出来后队列会把所有原图的节点加入queue
why dist[node]=0?
1 有负环 == 做完spfa后 存在点i dist[i] = -∞
2 赋的初值0也是有限值,做完spfa后都会变成-∞
3 w[node]都是有限值 则必然要更新无限次(更新次数>=n)

最后来个玄学操作
spfa O(m) ~ O(nm)
当spfa效率比较低的时候(一直结束不了的时候)
等价于 存在负环

可测量化:当所有点入队次数超过2n,我们就认为图中很大可能存在负环

作者:仅存老实人
链接:https://www.acwing.com/solution/content/20506/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

trick做法,老老实实地求有可能超时。
在这里插入图片描述

//这道题也有收藏题解,利用抽屉原理,判断一下最短路径上是否有超过n-1
//条边,cnt[i]存i号点到源点的最短路上,边的数量。
//这道题让判断整个图中有无负环、上一题是求1到n的最短路,这道题也并不是让求从1开始的负环
//所以题解中有个思想很好,就是假设一个虚拟原点,初始把所有的点都加到队列中

/*
    多加一个0号顶点,到其他顶点的距离都是零,求0到其他顶点的最短路,如果0到i号顶点的最短路中超过了n-1个节点
    那么整个图中必定存在负环。那么本题中就必定存在负环,所以说开始把所有顶点都加入到队列中的操作,等于上述设虚拟原点
    的操作,上述虚拟原点的新图中,0到任意一个点有负环,就等于原来的图中一定存在负环,可以画个图理解一下
    
*/
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>

using namespace std;

const int N=100010;

int n,m;
int h[N],w[N],ne[N],e[N],idx;
int dist[N], cnt[N];
bool st[N];

void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

bool spfa()
{
    //这里的把dist数组初始化为正无穷的操作也就不用了
    //因为我们最后注意的是cnt数组,而不是dist,dist刚开始是0的话也无所依
    //图中存在负环的话,cnt必然会>=n,相当于所有距离都减去了正无穷,但是并不
    //影响最后cnt的判断
    
    //更牛逼的解释来了!
    //  观察这个更新操作,if(dist[j] > dist[t] + w[i]) ) 
    //如果存在负环,则一定会更新无穷次。cnt数组肯定会>=n的 !所以不初始化dist也没事!!
    queue<int> q;
    
    for(int i=1;i<=n;i++)
    {
        st[i]=true;
        q.push(i);
    }
    
    while(q.size())
    {
        int t=q.front();
        q.pop();
        
        st[t]=false;
        
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
                dist[j]=dist[t]+w[i];
                cnt[j]=cnt[t]+1;
                
                if(cnt[j]>=n) return true;
                if(!st[j])
                {
                    q.push(j);
                    st[j]=true;
                }
            }
        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeof h);
    
    while(m--)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    
    if(spfa()) puts("Yes");
    else puts("No");
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
混沌系统的基本特点就是系统对初始值的极端敏感性,两个相差无几的初值所产生的轨迹,随着时间的推移按指数方式分离,lyapunov指数就是定量的描述这一现象的量。   Lyapunov指数是衡量系统动力学特性的一个重要定量指标,它表征了系统在相空间中相邻轨道间收敛或发散的平均指数率。对于系统是否存在动力学混沌, 可以从最大Lyapunov指数是否大于零非常直观的判断出来: 一个正的Lyapunov指数,意味着在系统相空间中,无论初始两条轨线的间距多么小,其差别都会随着时间的演化而成指数率的增加以致达到无法预测,这就是混沌现象。   Lyapunov指数的和表征了椭球体积的增长率或减小率,对Hamilton 系统,Lyapunov指数的和为零; 对耗散系统,Lyapunov指数的和为负。如果耗散系统的吸引子是一个不动点,那么所有的Lyapunov指数通常是负的。如果是一个简单的m维流形(m = 1或m = 2分别为一个曲线或一个面) ,那么,前m 个Lyapunov指数是零,其余的Lyapunov指数为负。不管系统是不是耗散的,只要λ1 > 0就会出现混沌。   微分动力系统L yapunov指数的性质   对于一维(单变量) 情形,吸引子只可能是不动点(稳定定态) 。此时λ是负的。对于二维情形, 吸引子或者是不动点或者是极限环。对于不动点,任意方向的δxi , 都要收缩, 故这时两个Lyapunov指数都应该是负的, 即对于不动点, (λ1 ,λ2 ) = ( - , - ) 。至于极限环,如果取δxi 始终是垂直于环线的方向,它一定要收缩,此时λ < 0;当取δxi沿轨道切线方向,它既不增大也不缩小,可以想像,这时λ = 0。事实上,所有不终止于定点而又有界的轨道(或吸引子) 都至少有一个Lyapunov指数等于零,它表示沿轨线的切线方向既无扩展又无收缩的趋势。所以极限环的Lyapunov指数是(λ1 ,λ2 ) = (0, - ) 。   在三维情形下有   (λ1 ,λ2 ,λ3 ) = ( - , - , - ) :稳定不动点;   (λ1 ,λ2 ,λ3 ) = (0, - , - ) :极限环;   (λ1 ,λ2 ,λ3 ) = (0, 0, - ) :二维环面;   (λ1 ,λ2 ,λ3 ) = ( +, +, 0) :不稳极限环;   (λ1 ,λ2 ,λ3 ) = ( +, 0, 0) :不稳二维环面;   (λ1 ,λ2 ,λ3 ) = ( +, 0, - ) :奇怪吸引子。   李雅谱诺夫指数小于零,则意味着相邻点最终要靠拢合并成一点,这对应于稳定的不动点和周期运动;若指数大于零,则意味着相邻点最终要分离,这对应于轨道的局部不稳定,如果轨道还有整体的稳定因素(如整体有界、耗散、存在捕捉区域等),则在此作用下反复折叠并形成混沌吸引子。指数越大,说明混沌特性越明显,混沌程度越高.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值