九度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]);
}
}
}