https://ac.nowcoder.com/acm/contest/4784/C
题解:
反过来想,一开始是 n n n个孤立节点,我要添加恰好 C n 2 − m C_n^2−m Cn2−m条边,让他连通块尽量剩余得多。
第一条肯定会让连通块数减少1,第二条也只能让连通块减少1,现在形成了一条包含三个点的链,接下来一条把这链的两个端点连起来,这一步没有让连通块的个数变少,再接下来一条边只能让连通块个数减少1…重复这样的过程:除非必须要把孤立点连进来,否则我就在大连通块内部连点。
形成 n − 1 , n − 2 , n − 3 , … , n − i n-1, n-2, n-3, \dots, n-i n−1,n−2,n−3,…,n−i 个连通块能用完的最大边数依次为: 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(n−1)−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)