离散实验3:平面图对偶图的求解
实验题目:
平面图对偶图的求解
实验目的:
- 掌握平面图的定义;
- 掌握平面图对偶图的求解方法;
- 掌握平面图与其对偶图之间顶点数、边数和面数的关系。
实验要求:
- 给定一平面图的面矩阵 R 和连通分支数 p 。
- 输出此平面图的顶点数 n、边数 m 和面数 r 。
- 输出此平面图的对偶图的顶点数 n、边数 m 和面数 r* 。
- 输出此平面图的对偶图的相邻矩阵 A,Aij 为 vi 与 vj 之间的边数(注意:面 Ri 中放置顶点 vi, 相邻矩阵第 i 行对应顶点 vi)。
说明:要求学生设计的程序不仅对给定面矩阵得出正确结果,还要对教师测试数据集得出正确结果,编程语言不限。
流程图:
源代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<vector>
using namespace std;
const int R = 100;//最大面数
const int M = 100;//最大边数
const int N = 100;//最大顶点数
int p;//连通分支数
int m;//边数
int n;//顶点数
int r;//面数
int rMatrix[R][M];//R行M列的面矩阵
int main() {
p = 0;
m = 0;
n = 0;
r = 0;
memset(rMatrix, 0, sizeof(rMatrix));
cout << "请输入平面图的面矩阵:" << endl;
while (1) {
char c;
c = getchar();
if (c == 10 || c == 13) {//如果是回车或者换行则跳出循环
break;
} else if (c != '0' && c != '1') {
cout << "输入错误,请输入 0 或 1 " << endl;
return 0;
} else {
string str;
getline(cin, str);//进行一行读取
rMatrix[r][0] = c - '0';
int j = 1;
for (int i = 0; i < int(str.size()); i++) {
//判断输入是否合法
if (str[i] != '0' && str[i] != '1' && str[i] != ' ' && str[i] != 10 && str[i] != 13) {
cout << "输入错误,请输入 0 或 1 " << endl;
return 0;
}
if (str[i] == '0' || str[i] == '1') {
rMatrix[r][j] = str[i] - '0';
j++;
}
}
m = j;
j = 1;
r++;
}
}
cout << "请输入连通分支数 p = ";
cin >> p;
n = m - r + p + 1;//欧拉公式
cout <<endl<< "该平面图的顶点数 n = " << n << ",边数 m = " << m << ",面数 r = " << r << endl;
//对偶图顶点数、边数、面数和原图的关系
cout << "其对偶图的顶点数 n* = " << r << ",边数 m* = " << m << ",面数 r* = " << n - p + 1 << endl;
//求对偶图的相邻矩阵,根据对偶图的定义和面矩阵的定义,原图的面矩阵可以看作其对偶图的关联矩阵
vector<vector<int>> A(r, vector<int>(r, 0));
for (int j = 0; j < m; j++) {
int edge[2] = {-1};//edge[0]和edge[1]分别储存一条边关联的两个顶点
int cnt = 0;//用于计数判断是不是悬挂边
for (int i = 0; i < r; i++) {
if(rMatrix[i][j] == 1) {
edge[cnt] = i;
cnt++;
}
}
if (cnt == 2) {//如果原图中一条边在两个面的边界上,则对偶图中这两个面上的顶点之间有一条边
A[edge[0]][edge[1]]++;
A[edge[1]][edge[0]]++;
} else if (cnt == 1) {//如果原图中一条边一个面的边界上,则对偶图中这个面上的顶点形成一个环
A[edge[0]][edge[0]]++;
}
}
//打印对偶图的相邻矩阵
cout << "其对偶图的关联矩阵为:" << endl
<< " ";
for (int i = 0; i < r; i++) {
printf("v%d ", i + 1);
}
cout << endl;
for (int i = 0; i < r; i++) {
printf("v%d ", i + 1);
for (int j = 0; j < r; j++) {
printf("%d ", A[i][j]);
}
printf("\n");
}
return 0;
}