生成树、环路空间、断集空间的求解
1、掌握无向连通图生成树的求解方法;
2、掌握基本回路系统和环路空间的求解方法;
3、掌握基本割集系统和断集空间的求解方法;
4、了解生成树、环路空间和断集空间的实际应用。
1、输出此图的关联矩阵M。
2、求此图所有生成树个数。
3、输出其中任意一棵生成树的相邻矩阵(默认第i行对应顶点vi)和关联矩阵(默认第i行对应顶点vi,第j列对应边ej)。
4、求此生成树对应的基本回路系统(输出形式如:{e1e4e3,e2e5e3}
)。
5、求此生成树对应的环路空间(输出形式如:{Φ,e1e4e3,e2e5e3,e1e4e5e2}
)。
6、求此生成树对应的基本割集系统(输出形式如:{{e1,e4},{e2,e5},{e3,e4,e5}}
)。
7、求此生成树对应的断集空间(输出形式如:{Φ,{e1,e4},{e2,e5},{e3,e4,e5},{e1,e2,e4,e5},{e1,e3,e5},{e2,e3,e4},{e1,e2,e3}}
)。
在相邻矩阵中,如果不为0,则表示这两点之间有边,如果大于1,表示有平行边,可以对相邻矩阵的每一行遍历,找到不为0的元素时,在新矩阵中新增一行,其中两点对应的位置置1,表示一条边,并同时将该元素和其关于主对角线元素-1,最后将矩阵输出即可。
def guanlian_matrix(l: list) -> list:
length = len(l)
lc = copy.deepcopy(l)
m = []
for i in range(length):
for j in range(length):
if lc[i][j] > 0:
for k in range(lc[i][j]):
t = [0] * length
t[i], t[j] = 1, 1
m.append(t)
lc[i][j] -= 1
lc[j][i] -= 1
return m
输出:
print("===>关联矩阵")
g = guanlian_matrix(m)
print(" ", end="")
[print('e' + str(i), end="\t") for i in range(len(g))]
print()
for i in range(len(g[0])):
print("v" + str(i), end=" ")
for j in range(len(g)):
print(g[j][i], end="\t")
print()
方法一:
设D(G)为图的度对角矩阵,A(G)为图的领接矩阵,则C = D ( G ) − A ( G ) 的任意一个余子式的值即为图G的生成树个数。C也成为拉式矩阵。分析得,拉式矩阵的对角线上的元素为相邻矩阵对应行上所有元素的求和,其他为相邻矩阵的相反数。得到拉式矩阵后,再取第一行第一列的余子式,也就是去除第一行和第一列的行列式。
求行列式,可以采用定义法,按第一行展开,得到的n个代数余子式,同样也是求行列式,再按照其第一行展开,一直递归到只剩一行时结束,即可算出行列式。这里使用了numpy中的函数实现。
def cal_tree(l: list) -> int:
m = []
for i in range(1, len(l)):
t = []
for j in range(1, len(l)):
if i == j:
t.append(sum(l[i]))
else:
t.append(-l[i][j])
m.append(t)
return int(round(np.linalg.det(np.array(m)), 0))
方法二:
可以去除关联矩阵中的任意一行,得到一个n-1行m列的矩阵,再在m条边中选择n-1条,组成一个新矩阵,计算该矩阵是否满秩,即计算行列式是否为0,如果不为0,则包含一个生成树。
def cal_tree(l: list) -> int:
x = list(itertools.combinations(range(len(l)), len(l[0]) - 1))
n = 0
for each in x:
matrix = [l[i][1:] for i in each]
if np.linalg.det(matrix) != 0:
n += 1
return n
利用上一题的方法二,取出其中的一个结果,其中从m中选出的n-1列就是选出的树枝。
对于排列组合,可以采用二进制枚举,从1 ~ 2n+1-1判断二进制数中有多少个1,如果符合需要组合的个数,则储存起来,其中1表示被选中,0表示不被选中。这里使用了itertools中的combination函数实现。
def tree(l: list) -> tuple:
x = list(itertools.combinations(range(len(l)), len(l[0]) - 1))
rep = []
for each in x:
matrix = [l[i][1:] for i in each]
if np.linalg.det(matrix) != 0:
rep = each
break
xianglin = [[0] * len(l[0]) for _ in range(len(l[0]))]
guanlian = [l[i] for i in rep]
# 根据关联矩阵计算相邻矩阵
for i in guanlian:
e = [j for j in range(len(i)) if i[j] == 1]
xianglin[e[0]][e[1]], xianglin[e[1]][e[0]] = 1, 1
return xianglin, guanlian, rep
输出:
x, y, bian = tree(g)
print("===>生成树的相邻矩阵")
print(" ", end="")
[print('v' + str(i), end="\t") for i in range(len(x))]
print()
for i in range(len(x)):
print("v" + str(i), end=" ")
for j in range(len(x)):
print(x[j][i], end="\t")
print()
print("===>生成树关联矩阵")
print(" ", end="")
[print('e' + str(i), end=" ") for i in bian]
print()
for i in range(len(y[0])):
print("v" + str(i), end=" ")
for j in range(len(y)):
print(y[j][i], end=" ")
print()
根据生成树的边,可以求出该生成树对应的弦,再根据每根弦的两个顶点,在生成树找到两个顶点的一条通路,加上这条弦,构成一条回路,于是可以求出基本回路系统。寻找通路时,采用了BFS宽度优先搜索,以生成树中的一个顶点为根节点,搜索时保存其子节点,最后再根据保存的字节点,为每个字节点的父节点赋值。根据另一个点,向回找到根节点即为一条回路。
class Node:
def __init__(self, num, pre=None):
self.pre = pre
self.num = num
self.succed = []
def bfs_loop(matrix: list, start: int, end: int):
points = [Node(i) for i in range(len(matrix))]
visited = [False] * len(matrix)
visited[start] = True
queue = [start]
# bfs搜索
while queue:
now = queue.pop(0)
if now == end:
break
for i in range(len(matrix)):
if matrix[now][i] == 1 and visited[i] == False:
points[now].succed.append(points[i])
queue.append(i)
visited[i] = True
# 为所有字节点的pre赋值,方便找到父节点
for each in points:
for i in each.succed:
i.pre = each
e = [end]
# 从端点向回找,找到根节点结束
while points[end].pre:
end = points[end].pre.num
e.insert(0, end)
return e
def loop(tree: list, guanlian: list, bian: list):
xian = list(set(range(len(guanlian))) - set(bian))
loops = []
# 计算每条弦的回路中的点
for each in xian:
e = [i for i in range(len(guanlian[0])) if guanlian[each][i] == 1]
x = bfs_loop(tree, e[0], e[1])
x.append(e[0])
loops.append(x)
rep = []
# 根据回路中的点求出对应的边
for each in loops:
n = 1
x = []
while n < len(each):
t = [0] * len(guanlian[0])
t[each[n - 1]], t[each[n]] = 1, 1
for i in range(len(guanlian)):
if guanlian[i] == t:
x.append('e' + str(i))
break
n += 1
rep.append(x)
return rep
可以对每一条树枝,先删除这条树枝,再以此加入弦,如果加入弦之后,图连通,则该弦应该再这条树枝生成的割集中,否则不在。判断连通,可以通过图的相邻矩阵进行bfs搜索,如果全部节点都被访问过的话,则为连通的。也可以使用实验一的方法。
def liantong(matrix: list) -> bool:
visited = [False] * len(matrix)
visited[0] = True
queue = [0]
# bfs搜索
while queue:
now = queue.pop(0)
for i in range(len(matrix)):
if matrix[now][i] == 1 and visited[i] == False:
queue.append(i)
visited[i] = True
return all(visited)
def geji(xianglin: list, bian: list, guanlian: list):
xian = list(set(range(len(guanlian))) - set(bian))
rep = []
for i in range(len(bian)):
xianglin1 = copy.deepcopy(xianglin)
# 删除树枝
e = [_ for _ in range(len(guanlian[0])) if guanlian[bian[i]][_] == 1]
xianglin1[e[0]][e[1]], xianglin1[e[1]][e[0]] = 0, 0
x = ['e' + str(bian[i])]
for each in xian:
# 加上一条弦
e = [_ for _ in range(len(guanlian[0])) if guanlian[each][_] == 1]
xianglin1[e[0]][e[1]], xianglin1[e[1]][e[0]] = 1, 1
if liantong(xianglin1):
# 如果连通则去除该弦,并加入割集
x.append('e' + str(each))
e = [_ for _ in range(len(guanlian[0])) if guanlian[each][_] == 1]
xianglin1[e[0]][e[1]], xianglin1[e[1]][e[0]] = 0, 0
rep.append(x)
return rep
环路空间只需要对生成树的基本回路系统中取若干个(1~n)做环合运算即可得到结果。环合运算可以取取出的若干个中的第一个回路生成数组A,对于后面的每一个回路,如果其中有边在A中,则在A中删除这条边,如果没有则在A中加入这条边。
取若干个的操作可以使用二进制枚举法,从1~2n-1,1为被选中,0为不被选中,即可枚举出所有选择的情况,这里使用itertools中的combination实现。
割集空间与环路空间同理。
def space(circles: list):
rep = copy.deepcopy(circles)
for i in range(2, len(circles) + 1):
x = itertools.combinations(range(len(circles)), i)
for e in x:
t = copy.deepcopy(circles[e[0]])
for j in e[1:]:
for each in circles[j]:
if each in t:
t.remove(each)
else:
t.append(each)
if t not in rep:
rep.append(t)
return rep
===>关联矩阵
e0 e1 e2 e3 e4 e5 e6
v0 1 1 1 0 0 0 0
v1 1 0 0 1 1 0 0
v2 0 1 0 1 0 1 0
v3 0 0 0 0 0 1 1
v4 0 0 1 0 1 0 1
共有24颗树
===>生成树的相邻矩阵
v0 v1 v2 v3 v4
v0 0 1 1 0 1
v1 1 0 0 0 0
v2 1 0 0 1 0
v3 0 0 1 0 0
v4 1 0 0 0 0
===>生成树关联矩阵
e0 e1 e2 e5
v0 1 1 1 0
v1 1 0 0 0
v2 0 1 0 1
v3 0 0 0 1
v4 0 0 1 0
===>基本回路系统
{ e0e1e3,e0e2e4,e5e1e2e6 }
===>环路空间
{ Φ, e0e1e3, e0e2e4, e5e1e2e6, e1e3e2e4, e0e3e5e2e6, e0e4e5e1e6, e3e4e5e6 }
===>基本割集系统
{ { e0,e3,e4 }, { e1,e3,e6 }, { e2,e4,e6 }, { e5,e6 } }
===>断集空间
{ Φ, { e0,e3,e4 }, { e1,e3,e6 }, { e2,e4,e6 }, { e5,e6 }, { e0,e4,e1,e6 }, { e0,e3,e2,e6 }, { e0,e3,e4,e5,e6 }, { e1,e3,e2,e4 }, { e1,e3,e5 }, { e2,e4,e5 }, { e0,e1,e2 }, { e0,e4,e1,e5 }, { e0,e3,e2,e5 }, { e1,e3,e2,e4,e5,e6 }, { e0,e1,e2,e5,e6 } }
import numpy as np
import copy
import itertools
def guanlian_matrix(l: list) -> list:
length = len(l)
lc = copy.deepcopy(l)
m = []
for i in range(length):
for j in range(length):
if lc[i][j] > 0:
for k in range(lc[i][j]):
t = [0] * length
t[i], t[j] = 1, 1
m.append(t)
lc[i][j] -= 1
lc[j][i] -= 1
return m
def cal_tree(l: list) -> int:
m = []
for i in range(1, len(l)):
t = []
for j in range(1, len(l)):
if i == j:
t.append(sum(l[i]))
else:
t.append(-l[i][j])
m.append(t)
return int(round(np.linalg.det(np.array(m)), 0))
# def cal_tree(l: list):
# x = list(itertools.combinations(range(len(l)), len(l[0]) - 1))
# n = 0
# for each in x:
# matrix = [l[i][1:] for i in each]
# if np.linalg.det(matrix) != 0:
# n += 1
# return n
def tree(l: list) -> tuple:
x = list(itertools.combinations(range(len(l)), len(l[0]) - 1))
rep = []
for each in x:
matrix = [l[i][1:] for i in each]
if np.linalg.det(matrix) != 0:
rep = each
break
xianglin = [[0] * len(l[0]) for _ in range(len(l[0]))]
guanlian = [l[i] for i in rep]
for i in guanlian:
e = [j for j in range(len(i)) if i[j] == 1]
xianglin[e[0]][e[1]], xianglin[e[1]][e[0]] = 1, 1
return xianglin, guanlian, rep
class Node:
def __init__(self, num, pre=None):
self.pre = pre
self.num = num
self.succed = []
def bfs_loop(matrix: list, start: int, end: int):
points = [Node(i) for i in range(len(matrix))]
visited = [False] * len(matrix)
visited[start] = True
queue = [start]
# bfs搜索
while queue:
now = queue.pop(0)
if now == end:
break
for i in range(len(matrix)):
if matrix[now][i] == 1 and visited[i] == False:
points[now].succed.append(points[i])
queue.append(i)
visited[i] = True
# 为所有字节点的pre赋值,方便找到父节点
for each in points:
for i in each.succed:
i.pre = each
e = [end]
# 从端点向回找,找到根节点结束
while points[end].pre:
end = points[end].pre.num
e.insert(0, end)
return e
def loop(tree: list, guanlian: list, bian: list):
xian = list(set(range(len(guanlian))) - set(bian))
loops = []
# 计算每条弦的回路中的点
for each in xian:
e = [i for i in range(len(guanlian[0])) if guanlian[each][i] == 1]
x = bfs_loop(tree, e[0], e[1])
x.append(e[0])
loops.append(x)
rep = []
# 根据回路中的点求出对应的边
for each in loops:
n = 1
x = []
while n < len(each):
t = [0] * len(guanlian[0])
t[each[n - 1]], t[each[n]] = 1, 1
for i in range(len(guanlian)):
if guanlian[i] == t:
x.append('e' + str(i))
break
n += 1
rep.append(x)
return rep
def space(circles: list):
rep = copy.deepcopy(circles)
for i in range(2, len(circles) + 1):
x = itertools.combinations(range(len(circles)), i)
for e in x:
t = copy.deepcopy(circles[e[0]])
for j in e[1:]:
for each in circles[j]:
if each in t:
t.remove(each)
else:
t.append(each)
if t not in rep:
rep.append(t)
return rep
def liantong(matrix: list) -> bool:
visited = [False] * len(matrix)
visited[0] = True
queue = [0]
# bfs搜索
while queue:
now = queue.pop(0)
for i in range(len(matrix)):
if matrix[now][i] == 1 and visited[i] == False:
queue.append(i)
visited[i] = True
return all(visited)
def geji(xianglin: list, bian: list, guanlian: list):
xian = list(set(range(len(guanlian))) - set(bian))
rep = []
for i in range(len(bian)):
xianglin1 = copy.deepcopy(xianglin)
# 删除树枝
e = [_ for _ in range(len(guanlian[0])) if guanlian[bian[i]][_] == 1]
xianglin1[e[0]][e[1]], xianglin1[e[1]][e[0]] = 0, 0
x = ['e' + str(bian[i])]
for each in xian:
# 加上一条弦
e = [_ for _ in range(len(guanlian[0])) if guanlian[each][_] == 1]
xianglin1[e[0]][e[1]], xianglin1[e[1]][e[0]] = 1, 1
if liantong(xianglin1):
# 如果连通则去除该弦,并加入割集
x.append('e' + str(each))
e = [_ for _ in range(len(guanlian[0])) if guanlian[each][_] == 1]
xianglin1[e[0]][e[1]], xianglin1[e[1]][e[0]] = 0, 0
rep.append(x)
return rep
m = []
x = input()
while x:
m.append(list(map(int, x.split())))
x = input()
print("===>关联矩阵")
g = guanlian_matrix(m)
print(" ", end="")
[print('e' + str(i), end="\t") for i in range(len(g))]
print()
for i in range(len(g[0])):
print("v" + str(i), end=" ")
for j in range(len(g)):
print(g[j][i], end="\t")
print()
tree_num = cal_tree(m)
print(f"共有{tree_num}颗树")
x, y, bian = tree(g)
print("===>生成树的相邻矩阵")
print(" ", end="")
[print('v' + str(i), end="\t") for i in range(len(x))]
print()
for i in range(len(x)):
print("v" + str(i), end=" ")
for j in range(len(x)):
print(x[j][i], end="\t")
print()
print("===>生成树关联矩阵")
print(" ", end="")
[print('e' + str(i), end=" ") for i in bian]
print()
for i in range(len(y[0])):
print("v" + str(i), end=" ")
for j in range(len(y)):
print(y[j][i], end=" ")
print()
print("===>基本回路系统")
circles = loop(x, g, bian)
print("{ ", end="")
for i in range(len(circles)):
if i != len(circles) - 1:
print(''.join(circles[i]), end=",")
else:
print(''.join(circles[i]), end=" ")
print(" }")
print("===>环路空间")
print("{ Φ, ", end="")
huanlu = space(circles)
for i in range(len(huanlu)):
if i != len(huanlu) - 1:
print(''.join(huanlu[i]), end=", ")
else:
print(''.join(huanlu[i]), end="")
print(" }")
print("===>基本割集系统")
gj = geji(x, bian, g)
print("{ ", end="")
for i in range(len(gj)):
print("{ ", end="")
if i != len(gj) - 1:
print(','.join(gj[i]), end=" }, ")
else:
print(','.join(gj[i]), end=" }")
print(" }")
print("===>断集空间")
dj = space(gj)
print("{ Φ, ", end="")
for i in range(len(dj)):
print("{ ", end="")
if i != len(dj) - 1:
print(','.join(dj[i]), end=" }, ")
else:
print(','.join(dj[i]), end=" }")
print(" }")
#include "iostream"
#include "vector"
#include "cmath"
#include "queue"
#include "algorithm"
using namespace std;
vector<vector<int>> guanlianMatrix(vector<vector<int>> l) {
vector<vector<int>> t;
for (int i = 0; i < l.size(); i++) {
for (int j = 0; j < l.size(); j++) {
if (l[i][j] > 0) {
for (int k = 0; k < l[i][j]; k++) {
vector<int> line;
line.assign(l.size(), 0);
line[i] = 1;
line[j] = 1;
t.push_back(line);
l[i][j]--;
l[j][i]--;
}
}
}
}
return t;
}
//获得det[i][j]余子式行列式
vector<vector<int> > complementMinor(vector<vector<int>> det, int i, int j) {
int n = det.size();//n为det的行,m为det的列;
vector<vector<int>> ans(n - 1);//保存获得的结果
for (int k = 0; k < n - 1; k++)
for (int l = 0; l < n - 1; l++) {
ans[k].push_back(det[k < i ? k : k + 1][l < j ? l : l + 1]);
}
return ans;
}
int Det(vector<vector<int>> det) {
int ans = 0;
int n = det.size(), m = det[0].size();//n为det的行,m为det的列;
if (n != m) {
exit(1);
}
if (det.size() == 1)
return det[0][0];
for (int i = 0; i < m; i++) {
ans += det[0][i] * pow(-1, i) * Det(complementMinor(det, 0, i));
}
return ans;
}
int treeNum(vector<vector<int>> l) {
vector<vector<int>> m;
for (int i = 1; i < l.size(); i++) {
vector<int> t;
for (int j = 1; j < l.size(); j++) {
if (i == j) {
int sum = 0;
for (int k: l[j]) {
sum += k;
}
t.push_back(sum);
} else {
t.push_back(-l[i][j]);
}
}
m.push_back(t);
}
return Det(m);
}
void
tree(vector<vector<int>> l, vector<vector<int>> &xianglin, vector<vector<int>> &guanlian, vector<unsigned int> &bian) {
for (int i = 1; i < 1 << l.size(); i++) {
bian.clear();
int n = 0;
unsigned int x = i, place = 0;
while (x) {
if (x & 0x1) {
bian.push_back(place);
n++;
}
x >>= 1;
place++;
}
if (n == l[0].size() - 1) {
// 去除第一行判断矩阵是否满秩
vector<vector<int>> matrix;
for (auto j: bian) {
vector<int> t;
for (int k = 1; k < l[j].size(); k++) {
t.push_back(l[j][k]);
}
matrix.push_back(t);
}
if (Det(matrix) != 0) break;
}
}
// 计算关联矩阵
for (auto x: bian) {
guanlian.push_back(l[x]);
}
for (int i = 0; i < l[0].size(); i++) {
vector<int> t;
t.assign(l[0].size(), 0);
xianglin.push_back(t);
}
// 计算相邻矩阵
for (auto i: guanlian) {
vector<int> e;
for (int j = 0; j < i.size(); j++) {
if (i[j] == 1) e.push_back(j);
if (e.size() == 2) break;
}
xianglin[e[0]][e[1]] = 1;
xianglin[e[1]][e[0]] = 1;
}
}
struct Node {
Node *parent;
int num;
};
vector<unsigned int> bfs_loop(const vector<vector<int>> &tree, int start, int end) {
vector<bool> visited;
visited.assign(tree.size(), false);
visited[start] = true;
vector<Node> points;
for (int i = 0; i < tree.size(); i++) {
Node t{nullptr, i};
points.push_back(t);
}
queue<int> q;
q.push(start);
while (!q.empty()) {
int now = q.front();
q.pop();
for (int i = 0; i < tree.size(); i++) {
if (tree[now][i] == 1 && !visited[i]) {
points[i].parent = &points[now];
q.push(i);
visited[i] = true;
}
}
if (now == end) break;
}
vector<unsigned int> road;
road.push_back(end);
while (points[end].parent) {
end = points[end].parent->num;
road.insert(road.begin(), end);
}
return road;
}
vector<vector<int>> loop(const vector<vector<int>> &xianglin, vector<vector<int>> guanlian, vector<unsigned int> bian) {
vector<unsigned int> xian;
for (int i = 0; i < guanlian.size(); i++) {
if (!count(bian.begin(), bian.end(), i)) {
xian.push_back(i);
}
}
vector<vector<unsigned int>> points;
for (auto x: xian) {
vector<unsigned int> e;
for (int i = 0; i < guanlian[0].size(); i++) {
if (guanlian[x][i] == 1) {
e.push_back(i);
}
}
vector<unsigned int> t = bfs_loop(xianglin, e[0], e[1]);
t.push_back(e[0]);
points.push_back(t);
}
vector<vector<int>> result;
for (auto x: points) {
int n = 1;
vector<int> t;
while (n < x.size()) {
vector<int> m;
m.assign(guanlian[0].size(), 0);
m[x[n - 1]] = 1;
m[x[n]] = 1;
for (int i = 0; i < guanlian.size(); i++) {
if (guanlian[i] == m) {
t.push_back(i);
break;
}
}
n++;
}
result.push_back(t);
}
return result;
}
bool liantong(vector<vector<int>> matrix) {
vector<bool> visited;
visited.assign(matrix.size(), false);
visited[0] = true;
queue<int> q;
q.push(0);
while (!q.empty()) {
int now = q.front();
q.pop();
for (int i = 0; i < matrix.size(); i++) {
if (matrix[now][i] == 1 && !visited[i]) {
q.push(i);
visited[i] = true;
}
}
}
for (auto x: visited) {
if (!x) return false;
}
return true;
}
vector<vector<int>>
geji(vector<vector<int>> xianglin, vector<vector<int>> guanlian, vector<unsigned int> bian) {
vector<unsigned int> xian;
for (int i = 0; i < guanlian.size(); i++) {
if (!count(bian.begin(), bian.end(), i)) {
xian.push_back(i);
}
}
vector<vector<int>> result;
for (auto x: bian) {
vector<vector<int>> t(xianglin.begin(), xianglin.end());
vector<int> e;
for (int i = 0; i < guanlian[0].size(); i++) {
if (guanlian[x][i] == 1) {
e.push_back(i);
}
}
t[e[0]][e[1]] = 0;
t[e[1]][e[0]] = 0;
vector<int> edge;
edge.push_back(x);
for (auto y: xian) {
// 添加一条弦
e.clear();
for (int i = 0; i < guanlian[0].size(); i++) {
if (guanlian[y][i] == 1) {
e.push_back(i);
}
}
t[e[0]][e[1]] = 1;
t[e[1]][e[0]] = 1;
if (liantong(t)) {
edge.push_back(y);
t[e[0]][e[1]] = 0;
t[e[1]][e[0]] = 0;
}
}
result.push_back(edge);
}
return result;
}
vector<vector<int>> space(const vector<vector<int>> &circles) {
vector<unsigned int> selected;
vector<vector<int>> result;
for (int i = 1; i < 1 << circles.size(); i++) {
selected.clear();
unsigned int x = i, place = 0;
while (x) {
if (x & 0x1) {
selected.push_back(place);
}
x >>= 1;
place++;
}
vector<int> t(circles[selected[0]].begin(), circles[selected[0]].end());
selected.erase(selected.begin());
for (auto e: selected) {
for (auto each: circles[e]) {
if (count(t.begin(), t.end(), each)) {
for (auto it = t.begin(); it != t.end();) {
if (*it == each) {
it = t.erase(it);
} else {
it++;
}
}
} else {
t.push_back(each);
}
}
}
result.push_back(t);
}
return result;
}
int main() {
int n, t;
cout << "请输入点的个数:" << endl;
cin >> n;
cout << "请输入矩阵" << endl;
vector<vector<int>> m;
for (int i = 0; i < n; i++) {
vector<int> temp;
for (int j = 0; j < n; j++) {
cin >> t;
temp.push_back(t);
}
m.push_back(temp);
}
vector<vector<int>> g = guanlianMatrix(m);
cout << "关联矩阵为:" << endl << " ";
for (int i = 0; i < g.size(); i++) {
cout << "e" << i << "\t";
}
cout << endl;
for (int i = 0; i < g[0].size(); i++) {
cout << "v" << i << " ";
for (auto &j: g) {
cout << j[i] << "\t";
}
cout << endl;
}
cout << "共有" << treeNum(m) << "颗树" << endl;
vector<vector<int>> xianglin, guanlian;
vector<unsigned int> bian;
tree(g, xianglin, guanlian, bian);
cout << "生成树的相邻矩阵为:" << endl << " ";
for (int i = 0; i < xianglin.size(); i++) {
cout << "v" << i << "\t";
}
cout << endl;
for (int i = 0; i < xianglin[0].size(); i++) {
cout << "v" << i << " ";
for (auto &j: xianglin) {
cout << j[i] << "\t";
}
cout << endl;
}
cout << "生成树关联矩阵为:" << endl << " ";
for (auto x: bian) {
cout << "e" << x << "\t";
}
cout << endl;
for (int i = 0; i < guanlian[0].size(); i++) {
cout << "v" << i << " ";
for (auto &j: guanlian) {
cout << j[i] << "\t";
}
cout << endl;
}
cout << "基本回路系统为:" << endl << "{ ";
vector<vector<int>> circle = loop(xianglin, g, bian);
for (int i = 0; i < circle.size(); i++) {
for (int j = 0; j < circle[i].size(); j++) {
cout << "e" << circle[i][j];
if (j == circle[0].size() - 1 && i != circle.size() - 1) cout << ", ";
}
}
cout << " }" << endl;
vector<vector<int>> huanlu = space(circle);
cout << "环路空间为:" << endl << "{ Φ ,";
for (int i = 0; i < huanlu.size(); i++) {
for (int j = 0; j < huanlu[0].size(); j++) {
cout << "e" << huanlu[i][j];
if (j == huanlu[0].size() - 1 && i != huanlu.size() - 1) cout << ", ";
}
}
cout << " }" << endl;
cout << "基本割集系统为:" << endl << "{ ";
vector<vector<int>> gj = geji(xianglin, g, bian);
for (int i = 0; i < gj.size(); i++) {
cout << "{ ";
for (int j = 0; j < gj[i].size(); j++) {
if (j == gj[i].size() - 1) {
cout << "e" << gj[i][j] << " } ";
if (i != gj.size() - 1) cout << ",";
} else {
cout << "e" << gj[i][j] << ",";
}
}
}
cout << " }" << endl;
cout << "断集空间为:" << endl << "{ Φ ,";
vector<vector<int>> dj = space(gj);
for (int i = 0; i < dj.size(); i++) {
cout << "{ ";
for (int j = 0; j < dj[i].size(); j++) {
if (j == dj[i].size() - 1) {
cout << "e" << dj[i][j] << " } ";
if (i != dj.size() - 1) cout << ",";
} else {
cout << "e" << dj[i][j] << ",";
}
}
}
cout << " }" << endl;
system("pause");
return 0;
}