Java算法-Dijkstra与SPFA模板

复习用


零、前言

在学习算法过程的一些笔记,下面记录了Dijkstra和SPFA算法Java版本,使用邻接表来存储图

一、Dijkstra模板

import java.util.*;

public class Main {
	static int n,m;
	
	public static void main(String[] args) {
		Scanner src = new Scanner(System.in);
		
		n = src.nextInt();
		m = src.nextInt();
		for(int i=0;i<=n;i++)arr[i] = new ArrayList<>();
		
		while(m--!=0)
		{
			int a=src.nextInt();
			int b=src.nextInt();
			int c=src.nextInt();
			
			arr[a].add(new PII(b,c));
		}
		
		System.out.println(dij());
	}
	static int[] dis = new int[200000];
	static int[] sta = new int[200000];
	static ArrayList<PII>[] arr = new ArrayList[10001];
	public static int dij() {
		Arrays.fill(dis, 10000000);
		
		dis[1] = 0;
		
		PriorityQueue<PII> queue = new PriorityQueue<>();
		queue.add(new PII(1,0));
		
		while(!queue.isEmpty())
		{
			
			PII a = queue.poll();//找到最小的
			
			if(sta[a.x]!=0)continue;
//			System.out.println(a.x+"------出队");
			sta[a.x]=1;
			
			for(int i=0;i<arr[a.x].size();i++)
			{
				PII aa = arr[a.x].get(i);
				if(dis[aa.x]>dis[a.x]+aa.y)
				{
				dis[aa.x] = dis[a.x] + aa.y;
//				System.out.println(aa.x+" 入队");
				queue.add(new PII(aa.x,dis[aa.x]));
				}
				
			}
			
		}
//		System.out.println(dis[4]);
		if(dis[n]!=10000000) {
			return dis[n];
		}else 
		return -1;
	}
	static class PII implements Comparable<PII>{
		int x;
		int y;
		PII(int x,int y){
			this.x = x;
			this.y = y;
		}
		@Override
		public int compareTo(PII o) {
			if(o.y!=this.y)return this.y-o.y;
			else return this.x - o.x;
		}
	}
	
}

/*
 下面这两个数据模拟一下可以发现有负权边dij算法不行
 【局部最优解不一定是全局最优解】
5 5 
1 2 2
2 4 2
1 3 5
3 4 -2
4 5 1
 
5 5
1 2 3
2 4 3
1 3 4
3 4 1
4 5 1
 
 
 */

二、SPFA模板

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
 * 模板
 * @author 边牧
 */

public class Main {
	
	static int n,m;
	static ArrayList<PII>[] arr = new ArrayList[10000000];
	public static void main(String[] args) {
		Scanner src = new Scanner(System.in);
		
		n = src.nextInt();
		m = src.nextInt();
		
		for(int i=0;i<=n;i++)
		arr[i] = new ArrayList<>();
		
		while(m--!=0)
		{
			int x = src.nextInt();int y = src.nextInt();int z = src.nextInt();
			arr[x].add( new PII(y,z) );
		}
		
		spfa();
	}
	
	
	static int dis[] = new int[10000000];
	static int sta[] = new int[10000000];
	static int spfa() {
		Arrays.fill(dis, 90000000);
		dis[1] = 0;
		
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(1);
		sta[1] = 1; //在队列里面就是 true
		
		while(!q.isEmpty())
		{
			int t = q.poll();
			sta[t]  = 0;
			
			for(int i=0;i<arr[t].size();i++) {
				int j = arr[t].get(i).a;
				if(dis[j] > dis[t] + arr[t].get(i).lon)
				{
					dis[j] = dis[t] + arr[t].get(i).lon;
					if(sta[j]==0)//如果不在队列里面就加入队列
					{
						q.add(j);
						sta[j] = 1;
					}
				}
			}
		}
		
		if(dis[n] >= 90000000/2)
		System.out.println("impossible");
		else System.out.println(dis[n]);
		return 1;
	}
	
	static class PII{
		int a;
		int lon;
		PII(int a,int lon){
			this.a = a;
			this.lon = lon;
		}
		PII(){
		}
	}
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值