离散实验3:平面图对偶图的求解

实验题目:

平面图对偶图的求解

实验目的:

  1. 掌握平面图的定义;
  2. 掌握平面图对偶图的求解方法;
  3. 掌握平面图与其对偶图之间顶点数、边数和面数的关系。

实验要求:

  1. 给定一平面图的面矩阵 R 和连通分支数 p 。
  2. 输出此平面图的顶点数 n、边数 m 和面数 r 。
  3. 输出此平面图的对偶图的顶点数 n、边数 m 和面数 r* 。
  4. 输出此平面图的对偶图的相邻矩阵 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;
}
posted @ 2023-04-21 22:03  catting123  阅读(43)  评论(0)    收藏  举报