标题: | 单元最短路径 |
时 限: | 1000 ms |
内存限制: | 10000 K |
总时限: | 3000 ms |
描述: | 给定一个带权有向图 G=(V,E) ,其中每条边的权是一个整数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权之和。这个问题通常称为单源最短路径问题. |
输入: |
第一行为一个整数n,表示包含源在内的顶点的个数,接下来是一个n*n的矩阵,矩阵中-1表示此路不通,否则表示从该顶点到另一顶点的距离。例如对于上图所示的问题我们可以按输入样例中的方式输入。 |
输出: | |
输入样例: | 5 -1 10 -1 30 100 -1 -1 50 -1 -1 -1 -1 -1 -1 10 -1 -1 20 -1 60 -1 -1 -1 -1 -1 |
输出样例: | 10 50 30 60 |
提示: | |
来源: |
贪心算法
import java.util.Scanner; public class Main { static int n = 0; static float[] dist = null; static int[] prev = null; public static void dijkstra(int v, float[][] a, float[] dist, int[] prev) { int n = dist.length - 1; if (v < 1 || v > n) return; boolean[] s = new boolean[n + 1]; for (int i = 1; i <= n; i++) { dist[i] = a[v][i]; s[i] = false; if (dist[i] == -1) prev[i] = 0; else prev[i] = v; } dist[v] = 0; s[v] = true; for (int i = 1; i < n; i++) { float temp = Float.MAX_VALUE; int u = v; for (int j = 1; j <= n; j++) { if (!s[j] && (dist[j] < temp)&&dist[j]!=-1) { u = j; temp = dist[j]; } } s[u] = true; for (int j = 1; j <= n; j++) { if (!s[j] && (a[u][j] != -1)) { float newdist = dist[u] + a[u][j]; if (newdist < dist[j]||dist[j]==-1) { dist[j] = newdist; prev[j] = u; } } } } } public static void main(String[] args) { // TODO Auto-generated method stub //System.out.println("请输入顶点个数n"); Scanner myscanner = new Scanner(System.in); n = myscanner.nextInt(); float[][] a = new float[n + 1][n + 1]; float[] dist = new float[n + 1]; int[] prev = new int[n + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { a[i][j] = (float) myscanner.nextInt(); } } dijkstra(1, a, dist, prev); for (int i = 2; i < n; i++) { System.out.print((int)dist[i]+" "); } System.out.println((int)dist[n]); } }