Likouソリューションの概要2039-ネットワークがアイドル状態の瞬間

ディレクトリリンク:

Likouプログラミングの質問-ソリューションの概要-共有+記録-CSDNブログ

GitHub同期ブラッシングプロジェクト:

https://github.com/September26/java-algorithms

オリジナルタイトルリンク:フォースバックル


説明:

0からn-1までの番号が付けられたn台のサーバーを備えたコンピューターネットワークが与えられます。同時に、2D整数配列エッジが与えられます。ここで、edges [i] = [ui、vi]は、サーバーuiとviの間にメッセージラインがあり、サーバーuiとviの間で任意の数のメッセージを転送できることを意味します。 2番目。長さnの別の整数配列の忍耐力と0から始まる添え字を提供します。

タイトルは、すべてのサーバーが接続されていることを保証します。つまり、任意のサーバーから開始されたメッセージが、これらの情報行を介して直接または間接的に他のサーバーに到達できることを保証します。

0の番号が付けられたサーバーはマスターサーバーであり、他のサーバーはデータサーバーです。各データサーバーはマスターサーバーに情報を送信し、応答を待ちます。メッセージはサーバー間で最適にルーティングされます。つまり、各メッセージは最短時間でメインサーバーに到着します。メインサーバーは、新しく到着したすべてのメッセージを処理し、各メッセージの送信元のルートとは反対の方向にすぐに応答を送信します。

0秒の開始時に、すべてのデータサーバーが処理に必要な情報を送信します。各データサーバーは、最初の1秒から開始し、各秒の開始時に、マスターサーバーから応答メッセージ(新しく送信されたメッセージの応答メッセージを含む)を受信したかどうかを確認します。

応答メッセージが受信されていない場合、サーバーは定期的にメッセージを再送信します。データサーバーiは、patience [i]秒ごとにメッセージを再送信します。つまり、データサーバーiは、最後にプライマリサーバーにメッセージを送信してからpatience[i]秒後にプライマリサーバーにメッセージを再送信します。
それ以外の場合、データサーバーはメッセージを再送信しません。
情報が有線で送信されないか、サーバーに到達しない場合、コンピューターネットワークはアイドル状態になります。

コンピュータネットワークがアイドル状態になる最も早い秒数を返してください。

例1:

入力:edges = [[0,1]、[1,2]]、patience = [0,2,1]
出力:8
説明:
0秒の開始時に、
-データサーバー1はマスターサーバーにメッセージを送信します(1A Expressを使用)。
-データサーバー2は、マスターサーバーにメッセージを送信します(2Aで示されます)。

1秒で、
-メッセージ1Aがメインサーバーに到着すると、メインサーバーはメッセージ1Aをすぐに処理し、1Aの応答メッセージを送信します。
-データサーバー1はまだ応答を受信して​​いません。最後のメッセージが送信されてから1秒が経過したため(1 <patience [1] = 2)、メッセージは再送されません。
-データサーバー2はまだ応答を受信して​​いません。最後のメッセージが送信されてから1秒が経過したため(1 == patience [2] = 1)、メッセージを再送信します(2Bで示されます)。

2秒で、
-応答メッセージ1Aがサーバー1に到着し、サーバー1はメッセージを再送信しません。
-メッセージ2Aがメインサーバーに到着すると、メインサーバーはメッセージ2Aをすぐに処理し、2Aの応答メッセージを送信します。
-サーバー2はメッセージを再送信します(2Cで示されます)。
...
4秒で、
-応答メッセージ2Aがサーバー2に到着し、サーバー2はメッセージを再送信しません。
...
7秒で、応答メッセージ2Dがサーバー2に到着します。

8秒以降、サーバー間で情報が送信されなくなり、サーバーに情報が到達しなくなります。
したがって、8秒は、ネットワークがアイドル状態になる最も早い瞬間です。
例2:

入力:edges = [[0,1]、[0,2]、[1,2]]、patience = [0,10,10]
出力:3
説明:データサーバー1および2は、 2秒の情報。
3秒目から、ネットワークはアイドル状態になります。
 

ヒント:

n == patience.length
2 <= n <= 105
patience [0] == 0
for 1 <= i <n、1 <= patience [i] <= 105
1 <= edges.length <= min(105、 n *(n-1)/ 2)
edges [i] .length == 2
0 <= ui、vi <n
ui!=vi
には重複するエッジはありません。
各サーバーは、他のサーバーに直接または間接的に接続されています。

出典:LeetCode
リンク:https ://leetcode-cn.com/problems/the-time-when-the-network-becomes-idle
著作権はLeetcodeNetworkに帰属します。商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。

問題解決のアイデア:

*問題解決のアイデア:
*まず、0で到達できるノードのセットを見つけ、次にこのセットに1ステップで到達できます。
*次に、このセットを通じて、到達可能なこのセット内の番号、つまり2つのステップで再帰的に到達できる番号を探し、到達可能なすべての番号を見つけます。
*次に、1ステップ、2ステップ、3ステップのセットを見つけ、各番号に費やした時間を見つけます。
*費やした時間は3つのケースに分けられます。
*1:忍耐の時間は往復時間以上であり、この時点で往復時間は2*ステップで使用できます。
* 2:往復時間は忍耐の時間の倍数に正確に等しく、費やされる時間は次のとおりです:2 *ステップ+(2 *ステップ/時間-1)*時間
* 3:往復時間は忍耐の時間の倍数に等しくありません。これに費やされる時間は次のとおりです。2*ステップ+(2 *ステップ/時間)*時間
*ここで、2*ステップ/時間は待機するサイクル数を表します。

コード:

public class Solution2039 {
//    public int networkBecomesIdle(int[][] edges, int[] patience) {
//        int n = patience.length;
//        List<Integer>[] adj = new List[n];
//        for (int i = 0; i < n; ++i) {
//            adj[i] = new ArrayList<Integer>();
//        }
//        boolean[] visit = new boolean[n];
//        for (int[] v : edges) {
//            adj[v[0]].add(v[1]);
//            adj[v[1]].add(v[0]);
//        }
//
//        Queue<Integer> queue = new ArrayDeque<Integer>();
//        queue.offer(0);
//        visit[0] = true;
//        int dist = 1;
//        int ans = 0;
//        while (!queue.isEmpty()) {
//            int size = queue.size();
//            for (int i = 0; i < size; i++) {
//                int curr = queue.poll();
//                for (int v : adj[curr]) {
//                    if (visit[v]) {
//                        continue;
//                    }
//                    queue.offer(v);
//                    int time = patience[v] * ((2 * dist - 1) / patience[v]) + 2 * dist + 1;
//                    ans = Math.max(ans, time);
//                    visit[v] = true;
//                }
//            }
//            dist++;
//        }
//        return ans;
//    }


    public int networkBecomesIdle(int[][] edges, int[] patience) {
        Set<Integer> allSet = new HashSet<>();
        Set<Integer>[] sets = new Set[patience.length];
        for (int i = 0; i < patience.length; i++) {
            if (i != 0) {
                allSet.add(i);
            }
            sets[0] = new HashSet<>();
        }
        for (int[] ints : edges) {
            int i1 = ints[0];
            int i2 = ints[1];

            Set<Integer> integers1 = sets[i1];
            if (i2 > 0) {
                integers1.add(i2);
            }

            Set<Integer> integers2 = sets[i2];
            if (i1 > 0) {
                integers2.add(i1);
            }
        }
        Map<Integer, Set<Integer>> levelMap = new HashMap<>();
        search(1, levelMap, allSet, sets[0], sets);
        System.out.println(levelMap.size());
        int max = 0;
        for (int step : levelMap.keySet()) {
            Set<Integer> integers = levelMap.get(step);
            for (int index : integers) {
                int time = patience[index];
                int minTime = step * 2;
                if (minTime <= time) {
                    //使用stepTime
                    max = Math.max(minTime, max);
                    continue;
                }
                if ((step * 2) % time == 0) {
                    max = Math.max(2 * step + (2 * step / time - 1) * time, max);
                    continue;
                }
                max = Math.max(2 * step + (2 * step / time) * time, max);
            }
        }
        return max + 1;
    }

    private void search(int level, Map<Integer, Set<Integer>> levelMap, Set<Integer> allSet, Set<Integer> set, Set<Integer>[] sets) {
        levelMap.put(level, set);
        allSet.removeAll(set);
        Set<Integer> newSet = new HashSet<>();
        for (Integer i : set) {
            Set<Integer> integers = sets[i];
            if (integers == null) {
                continue;
            }
            for (Integer value : integers) {
                if (allSet.contains(value)) {
                    newSet.add(value);
                    allSet.remove(value);
                }
            }
        }
        if (newSet.size() == 0) {
            return;
        }
        search(level + 1, levelMap, allSet, newSet, sets);
    }

}

おすすめ

転載: blog.csdn.net/AA5279AA/article/details/123614607