📜  门| GATE CS Mock 2018年|套装2 |问题9(1)

📅  最后修改于: 2023-12-03 15:12:38.463000             🧑  作者: Mango

门| GATE CS Mock 2018年|套装2 |问题9

问题描述

现有一个N个点的非权图,每条边都是无向的。给定一个起始节点S和终止节点T,计算从S到T的最短路径上第二个节点的度数。如果从S到T没有第二个节点,则输出-1。

输入格式

第一行包含一个整数T,表示测试用例的数量。

对于每个测试用例,第一行包含四个整数N,M,S和T,分别表示节点的数量,边的数量,起始节点的编号和终止节点的编号。

接下来M行每行包含两个整数u和v(1 ≤ u, v ≤ N,u ≠ v),表示节点u和节点v之间有一条无向边。

输出格式

对于每个测试用例,打印从S到T的最短路径上第二个节点的度数。如果从S到T没有第二个节点,则输出-1。

例子

输入:

2
3 3 1 3
1 2
1 3
2 3
4 4 1 4
1 2
2 3
3 4
4 2

输出:

2
3
解决方案

首先,将给定的图表示为邻接矩阵,这样我们可以很容易地找到最短路径上的节点。接下来,我们需要计算每个节点的度数,以找到第二个节点。我们可以使用适当的数据结构,如优先队列(PriorityQueue)来解决此问题。

以下是Java代码的示例,它实现了所提供的解决方案:

import java.util.*;

class ShortestPath {

    static int INF = Integer.MAX_VALUE;

    static int getSecondDegree(int[][] graph, int s, int t) {
        int n = graph.length;
        int[] dist = new int[n];
        Arrays.fill(dist, INF);
        dist[s - 1] = 0;
        PriorityQueue<Integer> q = new PriorityQueue<Integer>(n, new Comparator<Integer>() {
            public int compare(Integer a, Integer b) {
                return dist[a - 1] - dist[b - 1];
            }
        });
        q.add(s);
        int[] degree = new int[n];
        while (!q.isEmpty()) {
            int u = q.poll();
            if (u == t) break;
            for (int v = 1; v <= n; v++) {
                if (graph[u - 1][v - 1] > 0 && dist[u - 1] + graph[u - 1][v - 1] < dist[v - 1]) {
                    dist[v - 1] = dist[u - 1] + graph[u - 1][v - 1];
                    q.add(v);
                }
            }
        }
        for (int u = 1; u <= n; u++) {
            for (int v = 1; v <= n; v++) {
                if (graph[u - 1][v - 1] > 0 && dist[u - 1] + graph[u - 1][v - 1] == dist[v - 1]) {
                    degree[u - 1]++;
                    degree[v - 1]++;
                }
            }
        }
        int secondDegree = INF;
        for (int u = 1; u <= n; u++) {
            if (graph[s - 1][u - 1] > 0 && degree[u - 1] > 1) {
                secondDegree = Math.min(secondDegree, degree[u - 1]);
            }
        }
        return (secondDegree == INF) ? -1 : secondDegree;
    }

    static void runTests() {
        int[][] graph1 = {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}};
        System.out.println(getSecondDegree(graph1, 1, 3));

        int[][] graph2 = {{0, 1, 0, 0}, {1, 0, 1, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}};
        System.out.println(getSecondDegree(graph2, 1, 4));
    }

    public static void main(String[] args) {
        runTests();
    }
}

该程序首先将图表示为邻接矩阵,并将距离数组初始化为INT_MAX。然后我们创建一个优先队列,并将起始节点添加到它中。

接下来,我们使用类似Dijkstra算法的方法来计算最短路径,直到我们到达目标节点。我们还将每个节点的度数存储在数组中。

最后,我们检查从起始节点到其他节点的所有边,以找到第二个节点,并确定其度数。

请注意,这个程序是用Java编写的,但是您可以使用相应的语言来实现此算法。请注意,我们只需要从起始节点到其他节点的距离和每个节点的度数。因此,我们可以将程序优化为仅计算必要的内容,以减少时间和空间复杂性。

以上就是解决这个问题的一种可能的方法。