Strange Housing (Codeforces 1470D)
Tags: Greedy, graph matchings

Students of Winter Informatics School are going to live in a set of houses connected by underground passages. Teachers are also going to live in some of these houses, but they can not be accommodated randomly. For safety reasons, the following must hold:  All passages between two houses will be closed, if there are no teachers in both of them. All other passages will stay open.  It should be possible to travel between any two houses using the underground passages that are open.  Teachers should not live in houses, directly connected by a passage. Please help the organizers to choose the houses where teachers will live to satisfy the safety requirements or determine that it is impossible.

Input: The first input line contains a single integer $$$t$$$ — the number of test cases ($$$1 \le t \le 10^5$$$). Each test case starts with two integers $$$n$$$ and $$$m$$$ ($$$2 \le n \le 3 \cdot 10^5$$$, $$$0 \le m \le 3 \cdot 10^5$$$) — the number of houses and the number of passages.Then $$$m$$$ lines follow, each of them contains two integers $$$u$$$ and $$$v$$$ ($$$1 \le u, v \le n$$$, $$$u \neq v$$$), describing a passage between the houses $$$u$$$ and $$$v$$$. It is guaranteed that there are no two passages connecting the same pair of houses.The sum of values $$$n$$$ over all test cases does not exceed $$$3 \cdot 10^5$$$, and the sum of values $$$m$$$ over all test cases does not exceed $$$3 \cdot 10^5$$$.

Output: For each test case, if there is no way to choose the desired set of houses, output "NO". Otherwise, output "YES", then the total number of houses chosen, and then the indices of the chosen houses in arbitrary order.

Note: The picture below shows the second example test.   

Sample Inputs:
2
3 2
3 2
2 1
4 2
1 4
2 3

1
17 27
1 8
2 9
3 10
4 11
5 12
6 13
7 14
8 9
8 14
8 15
9 10
9 15
10 11
10 15
10 17
11 12
11 17
12 13
12 16
12 17
13 14
13 16
14 16
14 15
15 16
15 17
16 17

Sample Outputs:
YES
2
1 3 
NO

YES
8
1 3 4 5 6 9 14 17

Solution (Python):
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):

    def __init__(self, file):
        self.newlines = 0
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = 'x' in file.mode or 'r' not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b'\n') + (not b)
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            (self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode('ascii'))
        self.read = lambda : self.buffer.read().decode('ascii')
        self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline()

def RL():
    return map(int, sys.stdin.readline().split())

def RLL():
    return list(map(int, sys.stdin.readline().split()))

def N():
    return int(input())

def S():
    return input().strip()

def print_list(l):
    print(' '.join(map(str, l)))
for _ in range(N()):
    (n, m) = RL()
    (see, f) = ([0] * (n + 1), [0] * (n + 1))
    dic = [[] for _ in range(n + 1)]
    for _ in range(m):
        (u, v) = RL()
        dic[u].append(v)
        dic[v].append(u)
    now = [1]
    see[0] = see[1] = 1
    teacher = []
    while now:
        node = now.pop()
        live = 0
        if f[node] == 0:
            teacher.append(node)
            f[node] = 1
            live = 1
        for child in dic[node]:
            f[child] |= live
            if not see[child]:
                see[child] = 1
                now.append(child)
    if 0 in see:
        print('NO')
    else:
        print('YES')
        print(len(teacher))
        print_list(teacher)

Solution (Python):
from collections import deque
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def bfs(s):
    q = deque()
    q.append(s)
    visit = [0] * (n + 1)
    visit[s] = 1
    ans = []
    ng = [0] * (n + 1)
    cnt = 0
    while q:
        i = q.popleft()
        cnt += 1
        if not ng[i]:
            ans.append(i)
            for j in G[i]:
                ng[j] = 1
        for j in G[i]:
            if not visit[j]:
                visit[j] = 1
                q.append(j)
    return (ans, cnt)
t = int(input())
ans = []
for _ in range(t):
    (n, m) = map(int, input().split())
    G = [[] for _ in range(n + 1)]
    for _ in range(m):
        (u, v) = map(int, input().split())
        G[u].append(v)
        G[v].append(u)
    (ans0, cnt) = bfs(1)
    ans1 = 'YES' if cnt == n else 'NO'
    ans.append(ans1)
    if ans1 == 'NO':
        continue
    l = len(ans0)
    ans.append(l)
    ans.append(' '.join(map(str, ans0)))
sys.stdout.write('\n'.join(map(str, ans)))

Solution (Python):
import os
import sys
from io import BytesIO, IOBase

def main():
    for _ in range(int(input())):
        (n, m) = map(int, input().split())
        adjacencyList = []
        for _ in range(n):
            adjacencyList.append([])
        for _ in range(m):
            (x, y) = map(int, input().split())
            adjacencyList[x - 1].append(y - 1)
            adjacencyList[y - 1].append(x - 1)
        isCovered = [False] * n
        neighborList = [0]
        ans = []
        while neighborList:
            cur = neighborList.pop()
            if isCovered[cur]:
                continue
            ans.append(cur + 1)
            isCovered[cur] = True
            for elem in adjacencyList[cur]:
                if not isCovered[elem]:
                    isCovered[elem] = True
                    for elem2 in adjacencyList[elem]:
                        neighborList.append(elem2)
        if sum(isCovered) == n:
            print('YES')
            print(len(ans))
            print(' '.join(map(str, ans)))
        else:
            print('NO')
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = 'x' in file.mode or 'r' not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b'\n') + (not b)
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            (self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode('ascii'))
        self.read = lambda : self.buffer.read().decode('ascii')
        self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
if __name__ == '__main__':
    main()