A - 最短路

九度oj1447

D e s c r i p t i o n \color{blue}{Description} Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

I n p u t \color{blue}{Input} Input

输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
O u t p u t \color{blue}{Output} Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间

import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main{
	/*
	 * [7.27~8.2]最短路专题
	 * A - 最短路
	 * Floyd
	 */
	static int n,m,a,b,c,M=105;
	static int [][]g;
	static final int INF=Integer.MAX_VALUE;
	
	public static void main(String []args) {
		Scanner sc=new Scanner(System.in);
		g=new int [M][M];
		while(sc.hasNext()) {
			n=sc.nextInt();
			m=sc.nextInt();
			if(n==0&&m==0) break;
			//初始化邻接矩阵,节点相互间用INF表示不可到达。自己到达自己用0表示。
			for(int i=0;i<=n;i++) {
				Arrays.fill(g[i], INF);
				g[i][i]=0;
			}
//			show();
			//录入路径的两个节点,与路径长度。
			for(int i=1;i<=m;i++) {
				a=sc.nextInt();
				b=sc.nextInt();
				c=sc.nextInt();
				g[a][b]=c;
				g[b][a]=g[a][b];//无向图中节点与节点之间有两条边。
			}
//			show();
			//Floyd算法 核心:三层循环
			for(int k=1;k<=n;k++) {
				for(int i=1;i<=n;i++) {
					for(int j=1;j<=n;j++) {
						if(g[i][k]==INF||g[k][j]==INF) continue;//剪枝。
						if(g[i][j]>g[i][k]+g[k][j]) {
							g[i][j]=g[i][k]+g[k][j];
						}
					}
				}
			}
//			show();
			System.out.println(g[1][n]);
		}
	}
	static void show() {
		System.out.println();
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=n;j++) {
				System.out.print(g[i][j]+" ");
			}
			System.out.println();
		}
	}
}
/*
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0

3
2
 */


import java.util.Arrays;
import java.util.Scanner;

public class Main{
	/*
	 * [7.27~8.2]最短路专题
	 * A - 最短路
	 * Dijkstra:
	 *  1.是寻找特定点到其他所有节点的最短路径算法。
	 *  2.很好的支持了邻接表,和邻接矩阵。
	 *  3.时间复杂度为O(N*N),若在查找最小值处进行堆优化可以达到O(N*log(N))
	 *  K集合为已经确定到特定节点的最短路径长度的节点集合。U集合为整体集合除去k集合的部分。
	 * 
	 * 这道题要尤为注意INF的取值,不能取太大,不然在算法中会溢出。
	 */
	static int n,m,a,b,c,M=105;
	static int d[],g[][];
	static final int INF=(int)1e6;
	static boolean []vis;
	
	public static void main(String []args) {
		Scanner sc=new Scanner(System.in);
		g=new int [M][M];
		d=new int [M];
		vis=new boolean [M];
		while(sc.hasNext()) {
			n=sc.nextInt();
			m=sc.nextInt();
			if(n==0&&m==0) break;
			//初始化邻接矩阵,节点相互间用INF表示不可到达。自己到达自己用0表示。
			for(int i=1;i<=n;i++) {
				for(int j=1;j<i;j++) {
					g[i][j]=g[j][i]=INF;
				}
				g[i][i]=0;
			}
			//录入路径的两个节点,与路径长度。
			for(int i=1;i<=m;i++) {
				a=sc.nextInt();
				b=sc.nextInt();
				c=sc.nextInt();
				g[b][a]=g[a][b]=c;//无向图中节点与节点之间有两条边。
			}
			Dijkstra(1);
			System.out.println(d[n]);
		}
	}
	static void Dijkstra(int s) {
		int i,v,u;
		//初始化。将所有点都标记为未访问。将d数组赋初值。
		for(i=1;i<=n;i++) {
			vis[i]=false;
			d[i]=g[s][i];
		}
		//将起点设为0.
		d[s]=0;
		//循环。
		while(true) {
			//第一步:找到d数组当前未被访问过的,且值最小的点。
			v=-1;
			for(u=1;u<=n;u++) {
				if(!vis[u]&&(v==-1||d[u]<d[v])) v=u;
			}
			if(v==-1) break;//即没有符合要求的了。退出循环
			//标记该点,并更新数组。
			vis[v]=true;
			for(u=1;u<=n;u++)
				d[u]=Math.min(d[u], d[v]+g[v][u]);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值