【Java模板】SPFA模板

本文详细介绍了一种基于邻接表实现的SPFA算法,用于解决有向图中的最短路径问题。通过实例展示了算法的初始化过程、边的添加及SPFA算法的具体实现。特别关注了如何检测负权环的存在。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于邻接表(链表形式)实现。

import java.util.*;
public class SPFA模板 {
	static int N = 1005;
	static int len; //有向边个数 
	static int[] head = new int[N];
	static edge[] e = new edge[N];
	static int[] dis = new int[N];
	static boolean[] inq = new boolean[N]; //判断是否在队列里面
	static int[] cntInq = new  int[N]; //记录一个点入队列的次数 来判断是否有环
	
	
	static void add(int u, int v, int w) {
		e[len] = new edge(v, w, head[u]);
		head[u] = len++;
	}
	static void add2(int u, int v, int w) {
		add(u, v, w);
		add(v, u, w);
	}
	static void init() {
		Arrays.fill(head, -1);
		Arrays.fill(dis, 0x3f3f3f3f);
	}
	
	static int n,m;
	public static void main(String[] args) {
		init();
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		while (m-- > 0) {
			add2(sc.nextInt(), sc.nextInt(), sc.nextInt());
		}
		if (spfa(1)){
			System.out.println("有负环");
		} else {
			System.out.println(dis[n]);
		}
	}
	static boolean spfa(int u) {
		dis[u] = 0;//起点标记为0
		inq[u] = true; //放入队列
		cntInq[u]++;  //入队次数增加
		
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(u);
		
		while (q.size() != 0) {
			u = q.poll();
			inq[u] = false;
			
			for (int j = head[u]; j != -1; j = e[j].next) {
				int v = e[j].v;
				int w = e[j].w;
				if (dis[v] > dis[u] + w) {
					//进行跟新, 如果不在队中还应该放入队中
					dis[v] = dis[u] + w;
					if (!inq[v]) {
						//入队 且 次数加1
						cntInq[v]++;
						q.add(v);
						inq[v] = true;
						
						if (cntInq[v] > n) return true; //表明有负环
					}
				}
			}
		}
		
		return false;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值