首页 > 编程语言 >SPFA算法

SPFA算法

时间:2024-08-23 21:22:30浏览次数:13  
标签:dist idx int 算法 st SPFA include 号点

1.spfa求最短路

给定一个 n个点 m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你求出 1号点到 n号点的最短距离,如果无法从 1号点走到 n号点,则输出 impossible。
数据保证不存在负权回路。
输入格式
第一行包含整数 n和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x到点 y 的有向边,边长为 z。
输出格式
输出一个整数,表示 1号点到 n号点的最短距离。
如果路径不存在,则输出 impossible。
数据范围
1≤n,m≤105,
图中涉及边长绝对值均不超过 10000。
输入样例:
3 3
1 2 5
2 3 -3
1 3 4
输出样例:
2

#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>

using namespace std;

typedef pair<int,int> pii;

const int N = 1.5e5+5;
int h[N], w[N],idx, e[N], ne[N];
int n,m;
int dist[N];
bool st[N];
bool flag;

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

int spfa(){
    memset(dist,0x3f,sizeof dist);
    dist[1] = 0;
    queue<int> q;
    q.push(1);
    st[1] = true;
    while(!q.empty()){
        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];
                if(!st[j]){
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
    if(dist[n]==0x3f3f3f3f) {
        flag = true;
        return -1;
    }
    return dist[n];
}
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);
    }
    int t = spfa();
    if(t==-1 && flag) puts("impossible");
    else printf("%d\n",t);
    return 0;
}

2.spfa判断负环

给定一个 n个点 m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你判断图中是否存在负权回路。
输入格式
第一行包含整数 n和 m。
接下来 m行每行包含三个整数 x,y,z,表示存在一条从点 x到点 y的有向边,边长为 z。
输出格式
如果图中存在负权回路,则输出 Yes,否则输出 No。
数据范围
1≤n≤2000,
1≤m≤10000,
图中涉及边长绝对值均不超过 10000。
输入样例:
3 3
1 2 -1
2 3 4
3 1 -4
输出样例:
Yes

#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>

using namespace std;

typedef pair<int,int> pii;

const int N = 1.5e5+5;
int h[N], w[N],idx, e[N], ne[N];
int n,m; 
int dist[N],cnt[N]; 
bool st[N]; 
bool flag; 

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

int spfa(){ 
    queue<int> q; 
    for(int i=1;i<=n;i++){// 由于判断负环不一定是从1号点开始的,所以从1号点开始的所有点进入队列中
        st[i] = true; 
        q.push(i); 
    }
    while(!q.empty()){ 
        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);
    }
    bool t = spfa();
    if(t) puts("Yes");
    else puts("No");
    return 0;
}

标签:dist,idx,int,算法,st,SPFA,include,号点
From: https://blog.csdn.net/weixin_46006714/article/details/141459336

相关文章

  • 算法总结-树链剖分
    算法总结-树链剖分概念重儿子(红点):父节点\(f\)的子节点中子树大小最大的儿子。轻儿子(蓝点):父节点\(f\)的子节点中除重儿子以外的节点。重链(橙圈框出的链):链顶为轻儿子,由重儿子组成的链。重链剖分用处:将树上任意一条路径划分成不超过\(\log{n}\)条连续的链(如实......
  • 机器学习—KNN算法-分类及模型选择与调优
    KNN算法-分类样本距离判断:欧氏距离、曼哈顿距离、明可夫斯基距离KNN算法原理:        K-近邻算法(K-NearestNeighbors,简称KNN),根据K个邻居样本的类别来判断当前样本的类别;如果一个样本在特征空间中的k个最相似(最邻近)样本中的大多数属于某个类别,......
  • 2024“钉耙编程”中国大学生算法设计超级联赛(10)
    时间:08_181011NOI2024 31.80%(703/2211)1008SunBian 55.02%(669/1216)1009不基本子串结构 20.57%(589/2864)1002scenery 21.00%(368/1752)1011NOI2024思路题目问的是“是否一定”,考虑最差情况,比自己排名高的全部拿分了,剩下的人一分不拿,与自己并列排名最后每场......
  • 代码随想录算法训练营第 50 天 |98. 所有可达路径
    代码随想录算法训练营Day50代码随想录算法训练营第50天|98.所有可达路径目录代码随想录算法训练营前言LeetCode98.所有可达路径一、图论基础概念1、图的种类2、度3、连通性:节点的连通情况4、图的构造5、图的遍历方式二、深度优先搜索1、深度优先搜索的三部曲2......
  • 代码随想录算法训练营第 51 天 |LeetCode99岛屿数量 LeetCode100.岛屿的最大面积
    代码随想录算法训练营Day51代码随想录算法训练营第51天|LeetCode99岛屿数量LeetCode100.岛屿的最大面积目录代码随想录算法训练营前言LeetCode200岛屿数量LCR105.岛屿的最大面积一、广度优先搜索基础1、用队列实现2、代码框架:二、卡码网99岛屿数量(LeetCode......
  • 代码随想录算法训练营第 49 天 |LeetCode42 接雨水 LeetCode84 柱状图中最大面积矩形
    代码随想录算法训练营Day49代码随想录算法训练营第49天|LeetCode42接雨水LeetCode84柱状图中最大面积矩形目录代码随想录算法训练营前言LeetCode42接雨水LeetCode84柱状图中最大面积矩形一、LeetCode42接雨水1.题目链接2.思路3.题解二、LeetCode84柱状......
  • 代码随想录算法训练营第 48 天 |LeetCode 739. 每日温度 LeetCode496.下一个更大元素
    代码随想录算法训练营Day48代码随想录算法训练营第48天|LeetCode739.每日温度LeetCode496.下一个更大元素ILeetCode503.下一个更大元素II目录代码随想录算法训练营前言LeetCode739.每日温度LeetCode496.下一个更大元素ILeetCode503.下一个更大元素II一......
  • 从龟速乘到 $Miller-Rabin$ 算法(数论算法总结)
    发现自己竟然菜到不太会龟速乘,所以把\(Miller-Rabin\)算法所需要用到的算法全学了一遍……龟速乘龟速乘是一种\(O(\logn)\)的乘法计算方法。考虑有时普通乘法取模会爆\(long\long\),因此我们考虑用类似快速幂的方式进行乘法运算。intmul(intx,inty,intc){ x%=c,y%=......
  • 每天学习一个基础算法之选择排序
    目录前言:一、选择排序的基本思路和实现方法1、基本思路2、实现方法二、选择排序的执行过程示意图三、选择排序的实现代码选择排序代码主体(以接口函数的形式)测试部分(主函数调用) 四、对选择排序复杂度的分析背景知识:1、选择排序的时间复杂度 精确计算:*采用大O......
  • 24暑假算法刷题 | Day39 | 动态规划 VII | LeetCode 198. 打家劫舍,213. 打家劫舍 II,33
    目录198.打家劫舍题目描述题解213.打家劫舍II题目描述题解337.打家劫舍III题目描述题解打家劫舍的一天......