Dijkstra最短路径算法

创建图的结构体

顶点
边(weight)

package test;

import java.util.LinkedList;
import java.util.Scanner;



class Vertex{
	int id;
	LinkedList<Vertex> adj;
	boolean visited=false;
	Vertex(int i){
		adj=new LinkedList<>();		
		this.id=i;
	}
}

class Graph{
	
	Vertex vertex[];
	class Edge{
		int start;
		int end;
		int weight;
		
		void set(int start,int end,int weight) {
			this.start=start;
			this.end=end;
			vertex[start].adj.add(vertex[end]);
			this.weight=weight;
		}
		int getweight(int start,int end) {
			return this.weight;
		}
		Edge(){
			
		}
	}

	Edge edge[];

	Graph(int v,int n){
		vertex=new Vertex[v];
		edge=new Edge[n];
		for(int i=0;i<n;i++) {
			edge[i]=new Edge();
			
		}
	}
	int gw(int start,int end) {
		for(int i=0;i<edge.length;i++) {
			if(edge[i].start==start && edge[i].end==end) {
				return edge[i].getweight(start,end);
			}
		}
		return Integer.MAX_VALUE;
	}
	
}
public class Dijkstra {

	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int v=input.nextInt();//vertex number
		
		int start=input.nextInt();//dijkstra顶点
		int edge=input.nextInt();//edge number
		Graph graph=new Graph(v,edge);
		for(int i=0;i<v;i++) {
			graph.vertex[i]=new Vertex(i);
			
		}
			
		for(int i=0;i<edge;i++) {
			int p=input.nextInt();
			int q=input.nextInt();
			int weight=input.nextInt();
			graph.edge[i].set(p, q, weight);
			
		}
		int distto[]=new int[v];
		for(int i=0;i<v;i++) {
			distto[i]=Integer.MAX_VALUE;
		}
		distto[start]=0;
		graph.vertex[start].visited=true;
		LinkedList<Vertex> l=new LinkedList<>();
		l=graph.vertex[start].adj;
		
		int flag=start;
			int min=Integer.MAX_VALUE;
			for(int i=0;i<l.size();i++) {
				if(l.get(i).visited==false) {
					distto[l.get(i).id]=graph.gw(start, l.get(i).id);
					if(distto[l.get(i).id]<min) {
						min=distto[l.get(i).id];
						flag=l.get(i).id;
					}
				}
			}
			graph.vertex[flag].visited=true;

		l.clear();
		l=graph.vertex[flag].adj;
		while(!l.isEmpty()) {
			
			for(int i=0;i<l.size();i++) {
				if(l.get(i).visited==false) {
					if(distto[l.get(i).id]>distto[flag]+graph.gw(flag,l.get(i).id )) {
						distto[l.get(i).id]=distto[flag]+graph.gw(flag,l.get(i).id );
					}
				}
			}
			min=distto[l.get(0).id];
			flag=l.get(0).id;
			for(int i=0;i<l.size();i++) {
				if(min>distto[l.get(i).id]) {
					min=distto[l.get(i).id];
					flag=l.get(i).id;
					//System.out.println("flag"+flag);
				}
			}

//			for(int i=0;i<distto.length;i++) {
//				System.out.println(distto[i]);
//			}
//			System.out.println(flag);
			if(graph.vertex[flag].visited==false) {
				graph.vertex[flag].visited=true;
			}
			l.clear();
			l=graph.vertex[flag].adj;
			
		}	
//		LinkedList<Vertex> link=new LinkedList<>();
//		for(int i=0;i<v;i++) {
//			System.out.println(i);
//			link=graph.vertex[i].adj;
//			System.out.print(link);
//		}
//		System.out.println(graph.gw(2, 1));
//		
//			System.out.println(graph.gw(0, 1));
//			System.out.println(graph.gw(0, 2));
//			System.out.println(graph.gw(1,2));
//			System.out.println(graph.gw(1, 3));
//			System.out.println(graph.gw(1, 4));
//			System.out.println(graph.gw(2, 4));
//			System.out.println(graph.gw(3, 5));
//			System.out.println(graph.gw(3, 4));
//			System.out.println(graph.gw(4, 5));
		
		for(int i=0;i<distto.length;i++) {
			System.out.println(distto[i]);
		}
	}
	 
}
//6
//0
//9
//0 1 3
//0 2 5
//1 2 1
//1 3 2
//1 4 2
//2 4 4
//3 5 4
//3 4 2
//4 5 2

直接用LinkedList<int[]> graph[] 链表表示一张图,索引表示顶点,每个顶点的邻接边和权重用int[] 一维数组表示

package test;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;

class State{
	int id;
	int distFromStart;
	State(int id,int distFromStart){
		this.id=id;
		this.distFromStart=distFromStart;
	}
}
//class Edge{
//	int start;
//	int end;
//	int weight;
//	public void setWeight(int start,int end,int weight) {
//		this.start=start;
//		this.end=end;
//		this.weight=weight;
//	}
//	public int weight(int start,int end) {
//		return this.weight;
//	}
//}
public class NewDijkstra {

	public static LinkedList<int[]> adj(LinkedList<int[]> graph[],int s){
		return graph[s];
	}


	public static int[] dijkstra(LinkedList<int[]> graph[],int start) {//graph图,邻接表存储邻接点,边权重weight
		Set<State> set=new HashSet<>();
		int distto[]=new int[graph.length];
		Arrays.fill(distto, Integer.MAX_VALUE);
		distto[start]=0;
		//用优先级队列排序,按最短路径排,所以需要有一个类能存储图的节点和从start出发到这个节点的最短路径--State
		Queue<State> pq=new PriorityQueue<>((a,b)->(a.distFromStart-b.distFromStart));
		pq.add(new State(start,0)); //start->start---0
		while(!pq.isEmpty()) {
			
			State s=pq.poll();
			if(set.contains(s)) {
				continue;
			}
			set.add(s);
			int sid=s.id;
			int baseDis=s.distFromStart;
			LinkedList<int[]> gadj=adj(graph,sid);
			for(int i=0;i<gadj.size();i++) {
				int end=gadj.get(i)[0];
				int startDistEnd=gadj.get(i)[1];
				if(distto[end]>baseDis+gadj.get(i)[1]) {
					distto[end]=baseDis+gadj.get(i)[1];
					pq.add(new State(end,distto[end]));
					
				}
			}
		}
		return distto;
	}
	public static void main(String[] args) {
		int v=5;
		int edge=3;
		int start=0;
		
		
		Scanner input=new Scanner(System.in);
		//System.out.println("please input vertex number");
		v=input.nextInt();
		start=input.nextInt();
		//System.out.println("please input edge number");
		edge=input.nextInt();
		LinkedList<int[]> graph[]=new LinkedList[v];
		for(int i=0;i<v;i++) {
			graph[i]=new LinkedList<int[]>();
		}
		//邻接点,权重
		int dist[][]=new int[edge][2];
		int weight[]=new int[edge];
		//System.out.println("please input edge  from start to end");
		for(int i=0;i<edge;i++) {
			dist[i][0]=input.nextInt();
			dist[i][1]=input.nextInt();
			weight[i]=input.nextInt();
		}
//		for(int i=0;i<edge;i++) {
//			System.out.println(dist[i][0]);
//			System.out.println(dist[i][1]);
//			System.out.println(weight[i]);
//		}
		for(int g=0;g<v;g++)
		for(int i=0;i<edge;i++) {
			int[] adjw=new int[2];
				adjw[0]=dist[i][1];
				adjw[1]=weight[i];
				if(g==dist[i][0])
					graph[dist[i][0]].add(adjw);
		}
		for(int i=0;i<graph.length;i++) {
			LinkedList<int[]> gadj=adj(graph,i);
			System.out.println(i);
			for(int j=0;j<gadj.size();j++) {
				System.out.println(gadj.get(j)[0]+" "+gadj.get(j)[1]);
			}
			System.out.println();
		}
		int distto[]=dijkstra(graph,start);
		for(int i=0;i<distto.length;i++) {
			System.out.println(distto[i]);
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值