【JAVA】1003 Emergency (25分) PAT甲級(包含中文題目)

1003 Emergency緊急情況 (25分)

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.
作爲城市的緊急救援團隊負責人,您將獲得一張您所在國家的特殊地圖。 該地圖顯示了一些通過道路連接的分散城市。 地圖上標出了每個城市的救援隊數量以及每對城市之間的每條道路的長度。 當您收到其他城市的緊急電話時,您的工作是儘快帶領您的士兵前往該地點,同時,在途中儘可能多地多聚集救援團隊數量

Input Specification:
Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C1C_1​​andC2C_2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1c_1​​andc2c_2
​​ and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path fromC1C_1andC2C_2
輸入規格:
每個輸入文件包含一個測試用例。 對於每個測試用例,第一行包含4個正整數:N(≤500)-城市數量(並且城市從0到N-1編號),M-道路數量,$ C_1 $和 $ C_2 $ -當前所在的城市和必須援救的城市。
下一行包含N個整數,其中第i個整數是第i個城市中救援隊的數量。
然後是M行,每行描述了一條具有三個整數$ c_1 c_2 $ 和L的道路,分別是通過一條道路連接的兩個城市和該條道路的長度。 可以保證從$ C_1 C_2 $存在至少一條路徑

Output Specification:
For each test case, print in one line two numbers: the number of different shortest paths between C1C_1andC2C_2​​ , and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.
輸出規格:
對於每個測試用例,在一行中打印兩個數字:$ C_1 C_2 $之間的最短路的不同數量以及您可能會聚集的最大救援團隊數量。 一行中的所有數字必須完全由一個空格分隔,並且在行尾不允許有多餘的空格。

Sample Input:
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output:
2 4

代碼:dfs深度優先搜索

import java.util.Scanner;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author: 張志浩  Zhang Zhihao
 * @Email: [email protected]
 * @Date: 2020/4/29
 * @Time: 20:12
 * @Version: 1.0
 */
public class Emergency {
    static Scanner sc = new Scanner(System.in);
    static int N = sc.nextInt(); //城市數量 城市編號從0到N-1
    static int M = sc.nextInt(); //道路數量
    static int C1 = sc.nextInt(); //當前所在城市的編號
    static int C2 = sc.nextInt(); //需要救援的城市的編號
    static int[] weights = new int[N];//每個城市的救援隊的數量
    static int[][] map = new int[N][N]; //城市之間路的長度
    //城市間路被訪問的狀態,要是訪問了就更新爲true
    static boolean[][] visit = new boolean[N][N];
    static int minPath = Integer.MAX_VALUE; //剛開始的最小路徑的小設爲一個很大的值
    static int anspath = 0;
    static int answeights = 0;

    public static void main(String[] args) {
        for (int i = 0; i < N; i++) {
            weights[i] = sc.nextInt(); //每個城市的救援隊的數量
        }

        for (int i = 0; i < M; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            int z = sc.nextInt();
            map[x][y] = map[y][x] = z;
        }
        sc.close();

        dfs(C1, 0, weights[C1]);
        System.out.printf("%d %d", anspath, answeights);
    }

    public static void dfs(int start, int sumPath, int sumWeight) {
        if (start == C2) { //到達了終點C2(需要救援的城市的編號)
            if (sumPath < minPath) { //如果這條路的長度小於當前最短路的長度
                //更新最短路的長度
                minPath = sumPath;
                //將C1-C2之間的不同的路的數量更新爲1
                anspath = 1;
                //更新總權重,即救援隊總數量
                answeights = sumWeight;
            } else if (sumPath == minPath) { //如果這條路和最短路的長度一樣
                //將C1-C2之間的不同的路的數量增加1
                anspath++;
                //如果這條路救援隊總數量比之前最短路的總數量大,則更新救援隊總數量
                if (sumWeight > answeights) {
                    answeights = sumWeight;
                }
            }
            return;
        }
        //如果當前路的和的長度大於最小路長度(沒到達終點,及時退出)
        if (sumPath > minPath) return;
        for (int i = 0; i < N; i++) { //以C1點爲起點找到到其他各點的路
            if (!visit[start][i] && map[start][i] != 0) {
                //如果城市start和i之間的路沒有被訪問(無法保證start不等一i),並且路的長度不爲0(保證start不等一i)
                visit[start][i] = visit[i][start] = true; //更新訪問狀態
                dfs(i, sumPath + map[start][i], sumWeight + weights[i]); //遞歸,將起點更新爲i點
                visit[start][i] = visit[i][start] = false; //更新訪問狀態,很重要,注意一下
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章