有向图
题目
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;
}
}