Dijkstra和Floyd_warshall

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

/*题目描述:
 有n个城市,城市间有m条道路,每条道路都有长度d,给你起点城市s终点终点t,要求输出起点到终点的最短距离
 输入:
 输入n,m,城市的编号是1~n,然后是m行,每行3个数 a,b,d,表示a城市和b城市之间有一条道路,且其长度为d。假设a与b之间若有道路,则只

 有一条道路。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。(1<n<=1000, 0<m<100000, s != t)
 输出:
 输出一行有一个数, 表示最短距离。
 样例输入:
 3 2
 1 2 5
 2 3 4
 1 3
 0 0
 样例输出:
 9*/

/*
 * 起点s,终点t
 * map[a][b]表示a点与b点直接连通的距离,没有直接连通则为无限大
 * d[i]表示s点到i点的距离
 * fa[i]表示i点是否已经更新过了最短距离,true表示没有被使用,false表示已经被使用
 *
 * 大致过程如下:
 * 1.先从d数组里找到一个离起点最近的点k,而且fa[k]必须为true,距离为d[k]
 * 2.将fa[k]赋值为false,接下来将用k来更新最短距离
 * 3.任意一点j,且fa[j]为false,若d[k] + map[k][j]比d[j]小则将d[k] + map[k][j]赋值给d[j]
 * 	换句话说就是先从起点走到k点(d[k]),再从k点走到j(map[k][j]),若比从起点
 * 	到j的距离(d[j])短,则d[j]应该变为d[k] + map[k][j]
 * 4.回到步骤1,直到所有fa数组里所有点都为false。
 * 5.d[t]就是起点s到终点t的最短距离
 */
public class Dijkstra {

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		int m = cin.nextInt();
		while (n != 0 && m != 0) {
			int[][] map = new int[n + 5][n + 5];
			for (int i = 0; i < map.length; i++) {
				// 将map任意两点的初值设置一个很大的值,表示两点间的距离无限大,即没有通路
				// 除以3是因为后面有加的地方,我害怕两个值加会超过Integer.MAX_VALUE
				Arrays.fill(map[i], Integer.MAX_VALUE / 3);
			}
			for (int i = 1; i <= m; i++) {
				int a = cin.nextInt();
				int b = cin.nextInt();
				int c = cin.nextInt();
				// a点到b点的距离是c
				map[a][b] = c;// a到b的距离赋为c
				map[b][a] = c;// b到a的距离赋为c
			}
			int s = cin.nextInt();// 起点
			int t = cin.nextInt();// 终点
			// d数组:d[i]表示起点s到i点的最短距离
			int[] d = new int[n + 5];
			Arrays.fill(d, Integer.MAX_VALUE);
			// fa数组:fa[i]表示i点是否已经更新过了最短距离,true表示没有被使用,false表示已经被使用
			boolean[] fa = new boolean[n + 5];
			Arrays.fill(fa, true);// 初始值都为true,表示所有点都可以用
			fa[s] = false;// 起点不能更新自己,所以为false
			for (int i = 1; i <= n; i++) {
				d[i] = map[s][i];// d[i]的为题目给出的map[s][i]
			}
			// 将所有点的fa的值都变为false,因为s点已经为false,所以我这里写i<n而不是i<=n
			for (int i = 1; i < n; i++) {
				int min = Integer.MAX_VALUE;
				int k = 0;
				for (int j = 1; j <= n; j++) {
					if (fa[j] && min > d[j]) {
						min = d[j];// 找到一个最小的d[j]
						k = j;// 并记录下标为k

					}

				}
				fa[k] = false;// 这样接下来就不会出现d[k] + map[k][k]的情况了,k点在i增加时被抛弃
				for (int j = 1; j <= n; j++) {
					// if(j点可用 && 当前起点s到k的最短距离+k到j直接连通的距离<当前起点s到j的最短距离)
					if (fa[j] && d[k] + map[k][j] < d[j]) {
						d[j] = d[k] + map[k][j];// 找到了更优的s到j的最短距离
					}
				}

			}
			System.out.println(d[t]);// 整个过程之后d[t]就是s到t的最短距离了

			n = cin.nextInt();
			m = cin.nextInt();
		}

	}

}
import java.util.Arrays;
import java.util.Scanner;
/*题目描述和那道Dijkstra的题一样,不过这个时间复杂度是O(n^3),
 如果和上一道题一样,n要是最多1000的话,这个算法就会超时
看完了这个算法可以看看九度1447,分别用这两种算法都做一下
 这里有一篇别人写的博客可以参考一下:http://blog.csdn.net/jdplus/article/details/19816375
 */

/*
 * 起点s,终点t
 * map[a][b]表示a点与b点直接连通的距离,没有直接连通则为无限大
 * 这个代码很简单大致思路:
 * 分别把所有节点都当做媒介节点
 */
public class Floyd_warshall{

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        int m = cin.nextInt();
        while (n != 0 && m != 0) {
            int[][] map = new int[n + 5][n + 5];
            for (int i = 0; i < n + 5; i++){
                //和Dijkstra的算法一样我害怕会超过范围就除以了3
                Arrays.fill(map[i], Integer.MAX_VALUE / 3);
            }
            for (int i = 1; i <= m; i++) {
                int a = cin.nextInt();
                int b = cin.nextInt();
                int c = cin.nextInt();
                map[a][b] = c;
                map[b][a] = c;
            }
            //这个代码很简单,下面两段分割线之间就是最核心的代码
            //----------------------------------
            for (int k = 1; k <= n; k++)//k为媒介节点
                for (int i = 1; i <= n; i++)//i为所有的起点
                    for (int j = 1; j <= n; j++)//j为所有的终点
                    	/*
                    	 * 下面是最关键的两句:
                    	 * 如果i到k的距离加上k到j的距离比i到j的距离小,
                    	 * 则更新map[i][j]为map[i][k] + map[k][j]
                    	 * 就是不断把k当做中间节点来更新其他的两点的距离
                    	 */
                        if (map[i][k] + map[k][j] < map[i][j]) {//如果i到k的距离加上k到j的距离比i到j的距离小
                            map[i][j] = map[i][k] + map[k][j];//更新map[i][j]
                        }
            //----------------------------------
            int s = cin.nextInt();
            int t = cin.nextInt();
            System.out.println(map[s][t]);//更新后的map[s][t]已经是s到t的最短里的

            n = cin.nextInt();
            m = cin.nextInt();
        }

    }

}

九度1447可以两种方法都可以,九度1008只能用第一种方法

Dijkstra和Floyd_warshall

时间: 2024-10-14 02:33:18

Dijkstra和Floyd_warshall的相关文章

spring中controller

提示:原网站已由百度转码,以便在移动设备上查看. 第七城市 (Portal 开发读书笔记)Spring Portlet MVC 测试Controller 2012-04-28 16:32:44 - - 点击数: 175 测试Spring Portlet MVC 中的Controller有两种方法,一种是用mock对象,一种是用TestContext框架 测试1:用mock 对象测试Controller.我们把所有Controller用到或者依赖的对象全部mock掉. public class A

带权最短路 Dijkstra, SPFA, Bellman-Ford, ASP, Floyd-Warshall 算法分析

转载:https://www.renfei.org/blog/weighted-shortest-path.html 图论中,用来求最短路的方法有很多,适用范围和时间复杂度也各不相同. 本文主要介绍的算法的代码主要来源如下: Dijkstra: Algorithms(<算法概论>)Sanjoy Dasgupta, Christos Papadimitriou, Umesh Vazirani;<算法竞赛入门经典-训练指南>刘汝佳.陈峰. SPFA (Shortest Path Fas

POJ 3411-Paid Roads(状态压缩+dijkstra算法+floyd-warshall算法)

题目大意:给出一张有向图,求点1到点N的最短路,不同的是,对于每一条边,除了源点目标点和花费以外,还有额外点c,若走这条边之前到达过c点,花费会减少到另一个值P.如果最短路不存在,输出impossible. 先用floyd-warshall算法判断连通性,此时忽略额外的c和P. 然后用dijkstra算法,用d[i][S]表示在点i且经过了S集合的点的最短路,将每一个d[i][S]都看成一个点,用dijkstra算法计算. #include<stdio.h> #include<stdli

畅通project续HDU杭电1874【dijkstra算法 || SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了非常多年的畅通project计划后.最终修建了非常多路.只是路多了也不好,每次要从一个城镇到还有一个城镇时,都有很多种道路方案能够选择,而某些方案要比还有一些方案行走的距离要短非常多.这让行人非常困扰. 如今,已知起点和终点,请你计算出要从起点到终点.最短须要行走多少距离. Input 本题目包括多组数据.请处理到文件结束. 每组数据第一行包括两个正

Choose the best route 【Dijkstra】

Problem DescriptionOne day , Kiki wants to visit one of her friends. As she is liable to carsickness , she wants to arrive at her friend's home as soon as possible . Now give you a map of the city's traffic route, and the stations which are near Kiki

Bus System 【dijkstra算法】

Because of the huge population of China, public transportation is very important. Bus is an important transportation method in traditional public transportation system. And it's still playing an important role even now.The bus system of City X is qui

Dijkstra

//在这里采用两种方式实现Dijkstra算法,经过测试两种方式:第一种:通过Dist[]让每一个顶点中Dist[]中寻找最短路径的点:第二种方式:从已经收录的顶点的相邻顶点中选择出最短路//径的的顶点,此种方式适合用于稠密图,减少点的遍历. #include<iostream> #include<malloc.h> using namespace std; #define INF (100000) //相连顶点的信息 typedef struct AdjNode{ int Wei

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

ACM: HDU 3790 最短路径问题-Dijkstra算法

HDU 3790 最短路径问题 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. Input 输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p.最后一行是