title: 最大团问题
date: 2023-03-31 10:37:41
categories:
- 大学课程内容
- 大二下
- 算法分析基础
swiper_index: 10
7.最大团问题
【问题描述】
给定一个无向图G=(V,E),若U为V子集,请对任意的顶点u, v为U的元素,有边(u,v)为E元素,则称U为G的一个完全子图。G的完全子图U是一个团,当且仅当U不包含在G的更大的完全子图中。G的最大团则指包含定点数最多的团。对给定的无向图,找出最大团中顶点的个数。
【输入形式】
G的邻接矩阵
【输出形式】
第一行输出最大团顶点个数,第二行输出最大团中的顶点
【样例输入】
0,1,1,0,0
1,0,1,1,1
1,1,0,1,1
0,1,1,0,1
0,1,1,1,0
【样例输出】
最大团顶点个数: 4
最大团为: [0, 1, 1, 1, 1]
【样例说明】
输入的邻接矩阵表明图中有5个顶点,矩阵元素为1,则行、列对应的顶点有边相连,否则没有边相连。矩阵元素之间通过逗号隔开。举例:假设5个顶点分别为ABCDE,那么A与B、C相连。最终求得,最大团中包含4个节点,为BCDE。
完全图
任意两点都恰有一条边相连的图,n个顶点的图中有 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n−1) 条边。
完全子图(团)
任意两点都恰好有一条边相连的子图,也叫团。
思路
每次看当前点u如果他和最大团中的点没有边的话就不加,如果都有边的话,那么就加进去。
代码
graph = []
while True:
try:
graph.append(list(map(int, input().split(","))))
except:
break
n = len(graph[0])
# 用于存储最大团的点集
ans = [0 for _ in range(n)]
# 用于存储当前团的点集
st = [0 for _ in range(n)]
res = 1
def dfs(u, num):
global res, ans, n
if u == n:
if num > res:
res = num
ans = st[:]
return
flag = True
for i in range(n):
if st[i] == 1 and graph[u][i] == 0:
flag = False
break
if flag:
st[u] = 1
dfs(u + 1, num + 1)
st[u] = 0
dfs(u + 1, num)
else:
dfs(u + 1, num)
dfs(0, 0)
print("最大团顶点个数: {}".format(res))
print("最大团为: {}".format(ans))
三组测试数据如下
# Test1
0, 1, 1, 0, 0
1, 0, 1, 1, 1
1, 1, 0, 1, 1
0, 1, 1, 0, 1
0, 1, 1, 1, 0
# Result1
最大团顶点个数: 4
最大团为: [0, 1, 1, 1, 1]
# Test2
0, 1, 1, 1
1, 0, 1, 1
1, 1, 0, 1
1, 1, 1, 0
# Result2
最大团顶点个数: 4
最大团为: [1, 1, 1, 1]
# Test3
0, 1, 0, 0, 0, 1
1, 0, 1, 1, 1, 1
0, 1, 0, 1, 1, 0
0, 1, 1, 0, 1, 0
0, 1, 1, 1, 0, 1
1, 1, 0, 0, 1, 0
# Result3
最大团顶点个数: 4
最大团为: [0, 1, 1, 1, 1, 0]