最小断开次数

Posted

技术标签:

【中文标题】最小断开次数【英文标题】:Minimum number of disconnections 【发布时间】:2022-01-14 15:16:05 【问题描述】:

N 城市由N-1 道路连接。 每对相邻的城市都由双向道路连接,即

i-th city 与所有1 <= i <= N-1i+1-th city 相连,如下所示:

1 --- 2 --- 3 --- 4...............(N-1) --- N

我们得到M 类型的(c1, c2) 查询以断开 城市对 c1 和 c2。 为此,我们决定block 一些道路来满足所有这些M 查询。

现在,我们必须确定需要铺设的最少道路数量 阻止,以便为所有查询提供服务

示例:

inputs:
 -  N = 5 // number of cities
 -  M = 2 // number of query requests
 -  C = [[1,4], [2,5]] // queries

output: 1

Approach :
 1. Block the road connecting the cities C2 and C3 and all queries will be served.
 2. Thus, the minimum roads needs to be blocked is 1.

约束:

 - 1 <= T <= 2 * 10^5  // numner of test cases
 - 2 <= N <= 2 * 10^5  // number of cities
 - 0 <= M <= 2 * 10^5  // number of queries
 - 1 <= C(i,j) <=  N  

It is guaranteed that the sum of N over T test cases doesn't exceed 10^6.
It is also guaranteed that the sum of M over T test cases doesn't exceed 10^6.

我的方法

使用 Min-Heap 解决了这个问题,但不确定它是否有效 在所有 edges(corner) 测试用例上并具有 最优 时间/空间复杂性。

public int solve(int N, int M, Integer[][] c) 
    int minCuts = 0;
    if(M == 0) return 0;
    // sorting based on the start city in increasing order.
    Arrays.sort(c, (Integer[] a, Integer[] b) -> 
        return a[0] - b[0];
    );

    PriorityQueue<Integer> minHeap = new PriorityQueue<>();
    // as soon as I finds any end city in my minHeap which is less than equal to my current start city, I increment mincuts and remove all elements from the minHeap. 
    for(int i = 0; i < M ; i++) 
        int start = c[i][0];
        int end = c[i][1];

        if(!minHeap.isEmpty() && minHeap.peek() <= start) 
            minCuts += 1;
            while(!minHeap.isEmpty()) 
                minHeap.poll();
            
        
        minHeap.add(end);
    

    return minCuts + 1;

是否有任何这种方法会失败的边缘测试用例?

【问题讨论】:

“你能找到任何这种方法会失败的测试用例吗?”:看起来像一个题外话的问题。 在您之前提出的问题中,有 5 个有答案,但您只将一个答案标记为已接受。我在那里看到了一些很好的答案...您为什么不将令人满意的答案标记为已接受? ***.com/questions/4962015/… @trincot,我已经标记了接受的答案,并且几乎在我所有的问题中都对几乎所有答案都投了赞成票,我没有标记为接受的问题要么得到了作者很长的解释,因此需要是时候完全理解它了,或者它们刚刚在 2-3 天前发布,一旦我尽快验证,将尝试将它们标记为已接受。 @MattTimmermans,我读过你的方法。按结束时间排序,如果最后一个输出结束点小于该结束时间,则将当前结束点作为输出。我想我发布的 minHeap 解决方案会做同样的事情,也许它不像你的解决方案那样高效,因为我先排序,然后使用 min-heap 插入/删除。 【参考方案1】:

对于每个查询,都有一个(包括)可接受切点的区间,因此任务是找到与所有区间相交的最小切点数。

这个问题的常用算法,你可以看到here,是这个简单过程的优化实现:

    选择最小的区间结束作为切点 删除所有相交的区间 重复直到没有更多的间隔。

很容易证明选择最小的区间端总是最优的:

最小切点必须是 如果区间与任何点 因此,最小的区间末端是最小切割点的最佳选择。

这需要更多的工作,但你可以证明你的算法也是这个过程的一个实现。

首先,我们可以证明最小的区间 end 始终是第一个从堆中弹出的,因为在我们找到大于已知端点的起点之前不会弹出任何内容。

然后我们可以证明从堆中删除的端点正好对应于被第一个端点切割的间隔。它们的所有起点都必须是 peek() <= start。如果将它们调整为具有包容性,则会显示为peek() &lt; start

最后,我们可以简单地证明堆上总是有未弹出的间隔,所以最后需要+1

因此,您的算法对切割点进行了相同的最佳选择。不过,它比另一个更复杂,更难验证,所以我不会使用它。

【讨论】:

以上是关于最小断开次数的主要内容,如果未能解决你的问题,请参考以下文章

如何获得在图中将某个节点彼此断开连接的最小成本

如何在达到给定次数的点之后使GDB断点断开?

SSH 超时断开连接解决办法

Teamviewer11现在无法捕捉屏幕画面。这可能是由于快速的用户切换或远程桌面会话断开/最小化。

SSH超时断开(ClientAliveInterval和ClientAliveCountMax )的使用

SSH长时间不使用自动断开解决方案