首页 > 其他分享 >A*,spfa,和如何利用spfa判断负环

A*,spfa,和如何利用spfa判断负环

时间:2024-10-20 22:20:36浏览次数:1  
标签:cnt 判断 int 入队 负环 spfa add dis

A*即是在dij的思路上加上预估函数

注意:此处的欧式距离即为max(|x1-x2|,|y1-y2|);

   spfa算法

  每个点至多被松弛n-1次;

  我们利用队列来记录哪些点被松弛过(因为被松弛过说明距离变的更小,就有机会更新别人),一个点一旦出队,即取消标记

 

  那么我们又该如何判断负环呢?

  我们有一种最为稳定的办法(不会被某些特殊数据hack掉)

  即维护一个入队次数的数组,注意是入队次数,只有能被松弛且不在队列中才有机会入队。

  如果一个点的入队次数大于n-1说明一定存在负环。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100005;

int t,n,m; 
int head[N],nxt[N],to[N],cnt,val[N];

queue<int>q;

int num[N],dis[N],vis[N];

void add(int x,int y,int z)
{
    cnt++;
    nxt[cnt]=head[x];
    head[x]=cnt;
    to[cnt]=y;
    val[cnt]=z;
}


bool spfa()
{
        q.push(1);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            vis[x]=0;
            
            for(int i=head[x];i;i=nxt[i])
            {
                int y=to[i];
                if(dis[y]>dis[x]+val[i])
                {
                    dis[y]=dis[x]+val[i];
                    
                    
                    if(!vis[y])
                    {
                        if(++num[y]>=n)return 0;
                        vis[y]=1;
                        q.push(y);
                    }
                }
            }
        }
        return 1;
}
signed main()
{
    
    cin>>t;
    while(t--)
    {
        
        cin>>n>>m;
        for(int i=1;i<=n;i++)dis[i]=1e9;
        memset(num,0,sizeof(num));
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
        while(!q.empty())q.pop();
        cnt=0;
        dis[1]=0;
        num[1]=1;
        vis[1]=1;
        for(int i=1,u,v,w;i<=m;i++)
        {
            cin>>u>>v>>w;
            if(w>=0)
            {
                add(u,v,w);
                add(v,u,w);
            }
            else add(u,v,w);
        }
        
        if(spfa())cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    
    
    
    
    return 0;
}

 

 

标签:cnt,判断,int,入队,负环,spfa,add,dis
From: https://www.cnblogs.com/zbyQIN/p/18488063

相关文章

  • 如何判断自己是否处于程序员职业发展瓶颈期?
    作为程序员,可以从以下几个方面判断自己是否处于职业发展瓶颈期:一、工作表现方面技术提升缓慢:如果你发现自己在学习新技术时感到吃力,或者在现有的技术领域中很长时间没有实质性的进步,比如对于新的编程语言、框架或工具的掌握速度明显变慢,这可能意味着你进入了职业发展瓶颈......
  • 判断语句的编织艺术
    判断语句一、什么是判断?判断在生活中如何体现?判断就是通过选择最后得到不同的结果判断在我们的日常生活中无处不在。例如:天气判断:早上出门前,我们会判断今天是否需要带伞。如果天气预报显示会下雨,我们会选择带伞;如果显示晴天,我们可能选择不带伞。程序:我有20块钱,有两个......
  • 质数判断、质因子分解、质数筛
    质数判断、质因子分解、质数筛判断质数常规方法时间复杂度O(根号n)boolisPrime(longn){if(n<=1)returnfalse;longsq=sqrt(n);for(inti=2;i<=sq;++i)if(n%i==0)returnfalse;returntrue;}U148828素......
  • 代码随想录算法训练营 | 1143.最长公共子序列,1035.不相交的线,53. 最大子序和,392.判断
    1143.最长公共子序列题目链接:1143.最长公共子序列文档讲解︰代码随想录(programmercarl.com)视频讲解︰最长公共子序列日期:2024-10-17想法:这里的子序列不要求连续了,dp[i][j]要表示为在text1[0,i-1]和text2[0,j-1]的范围里,最长的公共子序列长度,-1同样是为了初始化方便,如果te......
  • 图论day64 :最短路径算法 | SPFA(Bellman_ford的队列优化版)、城市间货物运输 I、Ⅱ、Ⅲ
    图论day64:最短路径算法|SPFA(Bellman_ford的队列优化版)、94.城市间货物运输I(卡码网)【SPFA算法+邻接表优化】、95.城市间货物运输II(判断负权回路)、96.城市间货物运输III【已知有负权回路,该如何计算】、Bellman_ford算法思维导图汇总SPFA(Bellman_ford的队列优化版)94......
  • c#声明枚举,通过枚举int获取枚举value、通过枚举value获取int值、判断string值是否存在
    c#声明枚举,通过枚举int获取枚举value、通过枚举value获取int值、判断string值是否存在枚举中 1、声明枚举每个枚举常量可以用一个标识符来表示,也可以为它们指定一个整数值,如果没有指定,那么默认从 0 开始递增。注意:第一个枚举成员的默认值为整型的0,后续枚举成员的值在前......
  • C程序设计:判断并利用三边计算三角形面积
    在c语言中sqrt函数用于计算输入数的平方根。输入三角形的三边的长,做一步判断:如果三边长的数值合理(即可组成三角形),则开始利用三边计算三角形的面积。若其数值不合理则(输出信息有误)。利用复合语句。我们把一个三角形的而三边长设定为a,b,c,其面积为s。使用海伦公式即可编写出:#......
  • 《GESP5级2309 单选题判断题》 解析(附加编程题)
    温馨提醒,以下解析为个人观点,还是得请大佬多多指教(可以喷,但不能说我是复制粘贴!)一、单选题(每题2分,共30分)1、近年来,线上授课变得普遍,很多有助于改善教学效果的设备也逐渐流行,其中包括⽐较常用的手写板,那么它属于哪类设备?()。A.输入B.输出C.控制D.记录这是一道定义判断的......
  • 叉积法判断三点共线+重载运算符
    https://ac.nowcoder.com/acm/contest/92687/G#include<bits/stdc++.h>#defineendl'\n'#defineintlonglong#definelowbit(x)(x&-x)usingnamespacestd;constdoublepi=acos(-1);typedefpair<int,int>pii;piioperator-(piia,......
  • python根据时间字符串获取时间,判断是否非法定节假日时间
    fromdatetimeimportdatetimefromchinese_calendarimportis_workday,is_holiday,is_in_lieu,get_holiday_detail#定义两个时间字符串time_str1="2024-10-1218:41:02"time_str2="2024-10-1217:30:00"#将时间字符串转换为datetime对象time1=datetime.......