0543 - Bipartit 2

De la Universitas MediaWiki

Cerinţa

Se dă lista muchiilor unui graf neorientat conex cu n vârfuri, etichetate de la 1 la n. Să se verifice dacă graful este bipartit.

Date de intrare

Fişierul de intrare bipartit2in.txt conţine pe prima linie numerele n și m, reprezentând numărul de vârfuri ale grafului și numărul de muchii. Fiecare dintre următoarele m linii conține câte o pereche de numere i j, cu semnificația că există muchie între i și j.

Date de ieșire

Fişierul de ieşire bipartit2out.txt va conţine pe prima linie mesajul DA, dacă graful este bipartit, respectiv NU în caz contrar.

Dacă mesajul este DA, următoarele două linii vor conţine două mulţimi care formează partiţia vârfurilor. Elementele fiecărei mulţimi vor fi afişate în ordine crescătoare, separate prin exact un spaţiu. Prima mulţime va fi cea care conţine vârful 1.

Restricţii şi precizări

  • 1 ⩽ n ⩽ 100
  • 1 ⩽ i , j ⩽ n

Exemplul 1

bipartit2in.txt
7 6
1 4
1 6
6 5
3 2
3 5
3 7
bipartit2out.txt
Datele de intrare corespund resprictiilor impuse
DA
1 2 5 7 
3 4 6 

Exemplul 2

bipartit2in.txt
0 6
1 4
1 6
6 5
3 2
3 5
3 7
bipartit2out.txt
Datele de intrare nu corespund resprictiilor impuse

Rezolvare

from collections import defaultdict


def is_bipartite():
    with open('bipartit2in.txt', 'r') as fin:
        n, m = map(int, fin.readline().split())
        if n <= 1 or n > 100:
            return "Datele de intrare nu corespund resprictiilor impuse", [], []
        edges = [tuple(map(int, line.split())) for line in fin.readlines()]
        for u, v in edges:
            if u < 1 or u > n or v < 1 or v > n:
                return "Datele de intrare nu corespund resprictiilor impuse", [], []

    print("Datele de intrare corespund resprictiilor impuse")

    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)

    color = defaultdict(int)
    partition = defaultdict(list)
    for node in range(1, n+1):
        if node not in color:
            stack = [(node, 1)]
            while stack:
                node, c = stack.pop()
                color[node] = c
                partition[c].append(node)
                for neighbour in graph[node]:
                    if neighbour not in color:
                        stack.append((neighbour, -c))
                    elif color[neighbour] == color[node]:
                        return 'NU', [], []
    return 'DA', sorted(partition[1]), sorted(partition[-1])


result, group1, group2 = is_bipartite()
with open('bipartit2out.txt', 'w') as fout:
    fout.write(result + '\n')
    if result == 'DA':
        fout.write(' '.join(map(str, group1)) + '\n')
        fout.write(' '.join(map(str, group2)) + '\n')