L2-001 緊急救援 (25分)java

咿呀咿呀咿呀喲發表於2020-09-30

作為一個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連線城市的快速道路。每個城市的救援隊數量和每一條連線兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助電話給你的時候,你的任務是帶領你的救援隊儘快趕往事發地,同時,一路上召集儘可能多的救援隊。

輸入格式:

輸入第一行給出4個正整數N、M、S、D,其中N(2≤N≤500)是城市的個數,順便假設城市的編號為0 ~ (N−1);M是快速道路的條數;S是出發地的城市編號;D是目的地的城市編號。

第二行給出N個正整數,其中第i個數是第i個城市的救援隊的數目,數字間以空格分隔。隨後的M行中,每行給出一條快速道路的資訊,分別是:城市1、城市2、快速道路的長度,中間用空格分開,數字均為整數且不超過500。輸入保證救援可行且最優解唯一。

輸出格式:

第一行輸出最短路徑的條數和能夠召集的最多的救援隊數量。第二行輸出從S到D的路徑中經過的城市編號。數字間以空格分隔,輸出結尾不能有多餘空格。

輸入樣例:

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

輸出樣例:

2 60
0 1 3

 

程式碼:java最後一點超時

import java.util.Scanner;

public class Main{
    private static int[] dis,w,pre,num,weight;
    private static boolean[] vis;
    private static int n,m,s,d;
    private static int[][] G;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();m = sc.nextInt();
        s = sc.nextInt();d = sc.nextInt();
        dis = new int[n];vis = new boolean[n];w=new int[n];pre=new int[n];num=new int[n];
        weight = new int[n];
        G = new int[n][n];//鄰接矩陣
        for(int i = 0; i<n; i++){
            weight[i] = sc.nextInt();
            dis[i] = 1000;//設起點到達各點的最短距離
        }
        for(int i = 0; i<n; i++){
            for(int j = 0; j<n; j++){
                if(i != j)
                    G[i][j] = 1000;
            }
        }
        for(int i = 0; i<m; i++){
            int a = sc.nextInt();int b = sc.nextInt();int c = sc.nextInt();
            G[a][b] = c;
            G[b][a] = c;
        }
        Dijkstra(s);
        System.out.println( num[d]+" "+w[d]);
        dfs(s,d);
        System.out.println();

    }
    private static void dfs(int s,int v){
        if(s == v){
            System.out.print(s);
            return;
        }
        dfs(s,pre[v]);
        System.out.print(" "+v);
    }

    private static void Dijkstra(int s) {
        dis[s] = 0;//將起點到達自身的距離修改為0;
        num[s] = 1;//最短路徑條數初始化為1;
        w[s] = weight[s];//救援隊數目修改為起點城市的救援隊數目
        for (int i = 0; i<n; i++){
            int u = -1,min = 1000;
            for(int j = 0; j<n; j++){
                if(!vis[j] && dis[j] < min){
                    min = dis[j];
                    u = j;
                }
            }
            if(u == -1)return;
            vis[u] = true;
            for(int v = 0; v<n; v++){
                if(!vis[v] && G[u][v] != 1000 && dis[u] + G[u][v] < dis[v]){
                    dis[v] = dis[u] + G[u][v];
                    w[v] = w[u]+weight[v];
                    num[v] = num[u];
                    pre[v] = u;
                }else if(!vis[v] && G[u][v] != 1000 &&dis[u] + G[u][v] == dis[v]){
                    num[v] += num[u];//最短距離相同時路徑條數累加
                    if(w[v] < w[u]+weight[v]){
                        w[v] = w[u]+weight[v];
                        pre[v] = u;
                    }
                }
            }
        }

    }
}

 

相關文章