Розглянемо пов'язаний непрямий графік. Відповідний набір ребер на цьому графіку визначається як набір ребер таким чином, що жоден з двох ребер у множині не має спільної вершини. Наприклад, ліва цифра позначає відповідний набір зеленим кольором, тоді як права цифра позначає невідповідний набір червоним кольором.
Кажуть, що збігається набір maximally matching, або maximal matchingякщо неможливо додати інший край графіка до відповідного набору. Отже, обидва приклади, наведені вище, - це не максимальні відповідні множини, але обидва наведені нижче набори синього кольору - це максимальні відповідники. Зауважте, що максимальні відповідники не обов'язково є унікальними. Крім того, не потрібно вимагати, щоб розмір кожного можливого максимального відповідності для графа дорівнював іншому збігу.
Мета цього завдання - написати програму / функцію, щоб знайти максимальну відповідність графіка.
Вхідні дані
Припустимо, що всі вершини вхідного графіка мають деяку послідовну цілу нумерацію, починаючи з будь-якого початкового цілого значення на ваш вибір. Ребро описується не упорядкованою парою цілих чисел, що позначають вершини, з якими з'єднується край. Наприклад, графік, показаний вище, може бути описаний із наступним не упорядкованим набором ребер (якщо припустити, що нумерація вершин починається з 0):
[(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
Альтернативний спосіб опису графіка - це список суміжності. Ось приклад списку сумісності для наведеного вище графіка:
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
Ваша програма / функція повинна приймати як вхідний графік з будь-якого джерела (stdio, параметр функції тощо). Ви можете використовувати будь-які потрібні позначення до тих пір, поки додаткова нетривіальна інформація не буде передана вашій програмі. Наприклад, наявність додаткового параметра, що позначає кількість вхідних ребер, цілком прийнятна. Аналогічно, добре проходити в не упорядкованому безлічі ребер, списку суміжності або матриці суміжності.
Ви можете припустити:
- Графік пов'язаний (наприклад, можна досягти будь-якої вершини з будь-якою початковою вершиною).
- Є хоча б один край.
- Край ніколи не з'єднує вершину безпосередньо до себе (наприклад, край
(1,1)не буде вказаний як вхідний). Зауважте, що цикли все ще можливі (напр .: наведені вище графіки). - Вам може знадобитися, щоб вершини введення починалися з будь-якого індексу (наприклад, перша вершина може бути 0, 1, -1 тощо).
- Нумерація вершин послідовно збільшується від обраного вихідного індексу (напр .:
1,2,3,4,...або0,1,2,3,...).
Вихідні дані
Ваша програма / функція повинна виводити список ребер, що позначають максимальний набір відповідності. Ребро визначається двома вершинами, які з'єднують цей край. Вих. вихід для лівого синього набору (використовуючи приклад впорядкування вершин вхідних даних):
[(1,4), (2,3), (5,6)]
Зауважте, що порядок вершин не важливий; Отже, наступний вихід описує той самий набір відповідності:
[(4,1), (2,3), (6,5)]
Виходом може бути stdout, файл, значення повернення функції тощо.
Приклади
Ось кілька прикладів входів (використовуючи формат списку суміжності). Ці приклади трапляються для початку підрахунку вершин на 0.
Зауважте, що прикладів не наведено, натомість я включив код перевірки Python 3.
[0:(1), 1:(0)]
[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]
[0:(1,2), 1:(0,2,3,4,5), 2:(0,1), 3:(1), 4:(1), 5:(1)]
[0:(1,2), 1:(0,2,3), 2:(0,1,4), 3:(1,4,5), 4:(2,3), 5:(3)]
Перевірка коду Python 3
Ось код перевірки Python 3, який містить графік та набір ребер та друкує, чи відповідає цей набір максимально чи ні. Цей код працює з будь-яким індексом вершини початку.
def is_maximal_matching(graph, edges):
'''
Determines if the given set of edges is a maximal matching of graph
@param graph a graph specified in adjacency list format
@param edges a list of edges specified as vertex pairs
@return True if edges describes a maximal matching, False otherwise.
Prints out some diagnostic text for why edges is not a maximal matching
'''
graph_vtxs = {k for k,v in graph.items()}
vtxs = {k for k,v in graph.items()}
# check that all vertices are valid and not used multiple times
for e in edges:
if(e[0] in graph_vtxs):
if(e[0] in vtxs):
vtxs.remove(e[0])
else:
print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[0]))
return False
else:
print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
return False
if(e[1] in graph_vtxs):
if(e[1] in vtxs):
vtxs.remove(e[1])
else:
print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[1]))
return False
else:
print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
return False
if(e[1] not in graph[e[0]]):
print('edge (%d,%d): edge not in graph'%(e[0],e[1]))
return False
# check that any edges can't be added
for v in vtxs:
ovtxs = graph[v]
for ov in ovtxs:
if(ov in vtxs):
print('could add edge (%d,%d) to maximal set'%(v,ov))
return False
return True
Приклад використання:
graph = {0:[1,2], 1:[0,3,4], 2:[0,3], 3:[1,2,4,5], 4:[1,3], 5:[3,6], 6:[5]}
candidate = [(0,1),(2,3)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6),(0,1)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6)]
is_maximal_matching(graph, candidate) // True
Оцінка балів
Це код гольфу; виграє найкоротший код. Застосовуються стандартні лазівки. Ви можете використовувати будь-які бажані вбудовані модулі.

[[0 1] [3 4]]замість максимального набору[[0 2] [1 4] [3 5]]. (Я(1, 1)