【Java】最短路径--Dijkstra

有向图

题目

Description

有向图中某一顶点到其余各顶点的最短路径。带权图的最短路径是指两点间的路径中边权和最小的路径。

在这里插入图片描述

Input

输入有多个带权有向图的情况。每种情况先输入一行正整数m、n,分别表示有m个顶点、n条有向弧。顶点序号从0开始。接着有n行,每行3个正整数表示弧尾、弧头、权值。

Ouput

求出v0到图中其余每个顶点的路径及最短路径值,如果顶点i到顶点j,无路径输出vi->vj 无最短路径。

Sample Input

6 11
0 1 50
0 2 10
0 4 45
1 4 10
1 2 15
2 0 20
2 3 15
3 1 20
3 4 35
4 3 30
5 3 3

Sample Output

v0->v2->v3->v1 45
v0->v2 10
v0->v2->v3 25
v0->v4 45
v0->v5 无最短路径

代码

package 最短路径Dijkstra;

import java.util.Scanner;
import java.util.Stack;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		while (in.hasNext()) {
			int m = in.nextInt();
			int n = in.nextInt();
			Triple[] t = new Triple[n];
			for (int i = 0; i < n; i++) {
				t[i] = new Triple(in.nextInt(), in.nextInt(), in.nextInt());
			}
            Graph  g = new Graph(m,t);
            g.shortestPath(0);
		}
		in.close();
	}

}

class Graph {
	int vertexcount;
	Triple[] edge;

	public Graph(int vertexcount, Triple[] edge) {
		super();
		this.vertexcount = vertexcount;
		this.edge = edge;
	}
    public String getVet(int i) {
    	return "v"+i;
    }
    //获得路径值
	public int weights(int i, int j) {
		int t = Integer.MAX_VALUE;
		for (int k = 0; k < this.edge.length; k++)
			if (edge[k].getRow() == i && edge[k].getColumn() == j)
				t = edge[k].getWeight();
		return t;
	}

	public void shortestPath(int i) {
		int n = this.vertexcount;//顶点数
		boolean[] vset = new boolean[n];//已求出最短路径的顶点集合【已确定的点】
		vset[i] = true;
		int[] dist = new int[n];//最短路径值,会动态更新
		int[] path = new int[n];最短路径,会动态更新
		//先存放起点i与各个点的路径值和路径
		for (int j = 0; j < n; j++) {
			dist[j] = this.weights(i, j);
			path[j] = (j != i && dist[j] < Integer.MAX_VALUE) ? i : -1;
		}
		
		
		//判断i顶点与k顶点是否有连通,若有连通进行判断最短路径
		for (int j = (i + 1) % n; j != i; j = (j + 1) % n) {
			int mindist = Integer.MAX_VALUE, min = 0;//i顶点最小的路径值及最短路径及路径值对应的顶点
			//如果k未被确定,判断是否为最短路径 若是记录下来,并把k点标记为min,下面开始以min点寻找最短路径
			for (int k = 0; k < n; k++) {
				if (!vset[k] && dist[k] < mindist) {
					mindist = dist[k];
					min = k;
				}
			}
			if (mindist == Integer.MAX_VALUE)//判断是否是最后一个顶点,跳出循环
				break;
			
			vset[min] = true;//标记为已确定的顶点
			for (int k = 0; k < n; k++) {
				if (!vset[k] && this.weights(min, k) < Integer.MAX_VALUE
						&& dist[min] + this.weights(min, k) < dist[k]) {
                         dist[k] = dist[min]+this.weights(min, k);
                         path[k] = min;
				}
			}
			
		}
		for(int j=0;j<n;j++) {
			if(j!=i) {//如果不是起点
				Stack<String> pathStack = new Stack<String>();
				   /**
                 * k!=i 即不等于0 0为不连通
                 *  k!=j 不是自己连自己
                 *   k!=-1 不是最后一个点
                 */
				for(int k=path[j];k!=i && k!=j && k!=-1;k=path[k]) 
					pathStack.push(this.getVet(k));
				
					pathStack.push(this.getVet(i));
					while(!pathStack.isEmpty()) {
						String a = pathStack.pop();
						System.out.print(a+"->");
					}
					System.out.print(this.getVet(j)+" ");
					System.out.println(dist[j]==Integer.MAX_VALUE? "无最短路径":dist[j]);
				
			}
		}
	}
}

class Triple {
	int row, column, weight;

	public Triple(int row, int column, int weight) {
		this.row = row;
		this.column = column;
		this.weight = weight;
	}

	public int getRow() {
		return row;
	}

	public void setRow(int row) {
		this.row = row;
	}

	public int getColumn() {
		return column;
	}

	public void setColumn(int column) {
		this.column = column;
	}

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}

}

无向图

题目

Description

放假了,小王到一个度假村游玩。他手上有关于度假村的地图,图上标出了各个景点以及景点间的直接通路。请帮他找出从度假村的入口处(第一个景点所在的位置)到其他景点的最快走法。

Input

输入只有一个案例,第一行是两个正整数M、N。M代表景点的个数(5<=M<=10,景点的编号从0开始),N代表两个景点间的道路数。接下来是N条道路的信息,格式是S、D、L,分别代表两个景点的编号及它们之间通路的长度。接下来是一个正整数T,代表后面有T个提问,然后是T个目的景点的编号。

Ouput

根据样例输出.

Sample Input

6 9
0 1 1
0 2 4
1 2 2
1 3 7
1 4 5
2 4 1
3 4 3
3 5 2
4 5 6
2
5
3
Sample Output
V0到V5的最快走法是V0V1V2V4V3V5。
V0到V3的最快走法是V0V1V2V4V3。

代码

与有向图区别在于getWeight

package 图的最短路径;

import java.util.Scanner;
import java.util.Stack;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		while (in.hasNext()) {
            int m = in.nextInt();
            int n = in.nextInt();
            Triple[] tr = new Triple[n];
            for(int i=0;i<n;i++) {
            	tr[i] = new Triple(in.nextInt(),in.nextInt(),in.nextInt());
            }
            Graph g = new Graph(m,tr);
            g.shortPath(0);
            int t = in.nextInt();
            for(int i=0;i<t;i++) {
            	g.search(in.nextInt());
            }
		}
		in.close();
	}

}
class Graph{
	int vertexcount;
	Triple[] edge;
	int[] dist ;
	int[] path ;
	public Graph(int n, Triple[] edge) {
		super();
		this.vertexcount = n;
		this.edge = edge;
		dist = new int[n];
	    path = new int[n];
	}
	public String getV(int i) {
		return "V"+i;
	}
	public int getWeight(int i,int j) {//无向图
		int t = Integer.MAX_VALUE;
		for(int k=0;k<this.edge.length;k++) {
			if(edge[k].getRow()==i && edge[k].getColumn()==j || edge[k].getRow()==j && edge[k].getColumn()==i) {
				t=edge[k].getWeight();
			}
		}
		return t;
	}
	public void shortPath(int i) {
		int n = this.vertexcount;
		boolean[] vset = new boolean[n];
		vset[i] = true;
		for(int j=0;j<n;j++) {
			dist[j] = this.getWeight(i, j);
			path[j] = (j!=i && dist[j]<Integer.MAX_VALUE)? i:-1;
		}
		for(int j=(i+1)%n;j!=i;j=(j+1)%n) {
			int mindist = Integer.MAX_VALUE,min=0;
			for(int k=0;k<n;k++) {
				if(!vset[k] && dist[k]<mindist) {
					mindist = dist[k];
					min = k;
				}
			}
			if(mindist==Integer.MAX_VALUE)
				break;
			
			vset[min] = true;
			for(int k=0;k<n;k++) {
				if(!vset[k] && this.getWeight(min, k)<Integer.MAX_VALUE && 
						this.getWeight(min, k)+dist[min]<dist[k]) {
					dist[k] = dist[min] + this.getWeight(min, k);
					path[k] = min;
				}
			}
		}	
       
	}
	public void search(int key) {
		Stack<String> stack = new Stack<String>();
		
		for(int k=path[key];k!=0 &&k!=key && k!=-1;k=path[k]) {
			stack.push(this.getV(k));
		}
		stack.push(this.getV(0));//起点
		System.out.print("V0到V"+key+"的最快走法是");
		while(!stack.isEmpty()) {
			String a = stack.pop();
			System.out.print(a);
		}
		System.out.println("V"+key+"。");
	}
}
class Triple{
	private int row,column,weight;

	public Triple(int row, int column, int weight) {
		super();
		this.row = row;
		this.column = column;
		this.weight = weight;
	}

	public int getRow() {
		return row;
	}

	public void setRow(int row) {
		this.row = row;
	}

	public int getColumn() {
		return column;
	}

	public void setColumn(int column) {
		this.column = column;
	}

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}
	
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值