牛客小白月赛23 C 完全图(二分)

C 完全图

https://ac.nowcoder.com/acm/contest/4784/C

牛客小白月赛23 C 完全图(二分)_第1张图片
题解:
反过来想,一开始是 n n n个孤立节点,我要添加恰好 C n 2 − m C_n^2−m Cn2m条边,让他连通块尽量剩余得多。

第一条肯定会让连通块数减少1,第二条也只能让连通块减少1,现在形成了一条包含三个点的链,接下来一条把这链的两个端点连起来,这一步没有让连通块的个数变少,再接下来一条边只能让连通块个数减少1…重复这样的过程:除非必须要把孤立点连进来,否则我就在大连通块内部连点。

形成 n − 1 , n − 2 , n − 3 , … , n − i n-1, n-2, n-3, \dots, n-i n1,n2,n3,,ni 个连通块能用完的最大边数依次为: 1 , 3 , 6 , … , i ( i + 1 ) 2 1,3,6,\dots,\frac{i(i+1)}{2} 1,3,6,,2i(i+1)
二分可以解决,题目给定条件是最多删掉 m m m 条边,那么也可以是最少添加 n ( n − 1 ) 2 − m \frac{n(n-1)}{2}−m 2n(n1)m 条边。

Code:

T = int(input())
for i in range(T):
	# 两种输入方式
    # n, m = [int(x) for x in input().split()]
    n, m = map(int, input().split())
    add = max(0, n*(n-1)//2 - m)
    l, r = 0, n-1
    while l < r:
        mid = (l+r) >> 1
        if (mid*(mid+1) >> 1) >= add:
            r = mid
        else:
            l = mid+1
    print(n-r)

你可能感兴趣的:(二分三分)