很多大佬都写过这题的题解 我就提供一下python AC的方式吧 离散化过程有两种写法,一种是比较标准的去重、排序加二分,另一种就是比较懒直接用字典存图和用字典vis。

一开始建图对每个连通块的遍历想的是dfs,简单嘛,但爆栈了,加栈后超时,段错误..... 所以改成了bfs, emmm用了queue库的Queue当队列超时,后来想了想这个支持多线程 肯定慢啊QAQ。得改成collections库的deque当队列使用 AC 了。 下面分别给出pypy3离散化 和 字典的代码吧

贴出两种的用时: alt

离散化的AC代码

import sys
from collections import deque

def bfs(r):
    global cnt1,cnt2
    q = deque()
    q.append(r)
    while q:
        x = q.popleft()
        if vis[x]: continue
        vis[x] = True
        cnt1 += 1
        for y in g[x]:
            cnt2 += 1
            q.append(y)
        
def find(x):
    l,r = 0, len(alls)
    while l < r:
        mid = (l+r)//2
        if alls[mid] >= x: r = mid
        else: l = mid + 1
    return r

t = int(sys.stdin.readline())
case = 0
while t > 0:
    t -= 1
    case += 1
    n = int(sys.stdin.readline())
    alls,ls = [],[]
    ans = 0
    for _ in range(n):
        a,b = map(int, sys. stdin.readline().split())
        ls.append((a,b))
        alls.append(a)
        alls.append(b)
    alls = sorted(set(alls))
    g = {i: [] for i in range(len(alls)+1)}
    for i in range(len(ls)):
        a,b = ls[i]
        a,b = find(a),find(b)
        g[a].append(b)
        g[b].append(a)
    vis = [False]*(len(alls)+1)
    for i in range(len(alls)):
        cnt1,cnt2 = 0,0
        if not vis[i]:
            bfs(i)
            ans += min(cnt1,cnt2//2)
    print(f'Case #{case}: {ans}')

用字典的AC代码

import sys
from collections import deque

def bfs(r):
    global cnt1,cnt2
    q = deque()
    q.append(r)
    while q:
        x = q.popleft()
        if x in vis: continue
        vis.add(x)
        cnt1 += 1
        for y in g[x]:
            cnt2 += 1
            q.append(y)


t = int(sys.stdin.readline())
case = 0
while t > 0:
    t -= 1
    case += 1
    n = int(sys.stdin.readline())
    g, ans = {}, 0
    for i in range(n):
        x,y = map(int, sys.stdin.readline().split())
        if x in g: g[x].append(y)
        else: g[x] = [y]
        if y in g: g[y].append(x)
        else: g[y] = [x]
    vis = set()
    for i in g:
        cnt1,cnt2 = 0,0
        if i not in vis:
            bfs(i)
            ans += min(cnt1,cnt2//2)
    print(f'Case #{case}: {ans}')