图论---无向图中国邮路的实现

news2024/9/23 21:30:47

开始编程前分析设计思路和程序的整体的框架,以及作为数学问题的性质:

程序流程图:

数学原理:

        本质上是找到一条欧拉回路,考虑图中的边权重、顶点的度数以及如何通过添加最少的额外边来构造欧拉回路,涉及到欧拉回路、最短路径算法以及奇点匹配。

时间复杂度分析:

        程序的时间复杂度主要来自于Floyd算法和ADD函数。Floyd是动态规划算法。它的时间复杂度是O(n^3)。 ADD函数是一个递归函数它的时间复杂度是O(2^n),其中n是奇点的数量。在最坏情况下,奇点的数量可能接近于节点的数量,ADD函数的时间复杂度可能接近于O(2^n)。综合看,这段程序的时间复杂度是O(n^3 + 2^n)。由于2^n的增长速度非常快,当n较大时,2^n将远大于n^3,因此这段程序的时间复杂度应该为O(2^n)

源代码:

#include <stdio.h>
#include <bits.h>
// 定义常量
const int N = 105;
const int inf = 100000000;
// 建立矩阵和路径数组
int matrix[N][N], mapp[N][N];
int p[N][N];
int path[N], d[N];
int sg[N];
int cont[N];
int vis[N];
int n, m;
int top;
// 设置结构体将边和权重关联
struct node
{
    int v, u, cost;
} gg[N];
// 使用深度优先递归搜索
void DFS(int beg)
{
    for (int i = 1; i <= n; i++)
    {
        if (matrix[beg][i])
        {
            matrix[beg][i]--;
            matrix[i][beg]--;
            DFS(i);
        }
    }
    path[top++] = beg;
}
void Fleury(int beg)
{
    top = 0;
    DFS(beg);
}
// 寻找最短路径
void Floyed()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            for (int k = 1; k <= n; k++)
            {
                if (mapp[i][j] > mapp[i][k] + mapp[k][j])
                {
                    p[i][j] = k;
                    mapp[i][j] = mapp[i][k] + mapp[k][j];
                }
            }
        }
    }
}
// 通过递归对奇数边进行加边
int ADD(int cn)
{ // 将奇点进行匹配得一个最小的
    int ans = inf;
    if (cn < 2)
        return 0; // 奇点个数小于2,无需匹配。
    for (int i = 1; i <= cn; i++)
    {
        if (sg[i] != 0)
        {
            for (int j = i + 1; j <= cn; j++)
            {
                if (sg[j] != 0)
                {
                    int tem1 = sg[i], tem2 = sg[j];
                    sg[i] = 0;
                    sg[j] = 0;
                    if (ans > ADD(cn - 2) +mapp[tem1][tem2])
                    {
// 第i个奇点匹配的奇点是第j个奇点
                        cont[i] = tem2; 
// 第j个奇点匹配的奇点是第i个奇点
                        cont[j] = tem1; 
                        ans = ADD(cn - 2)+mapp[tem1][tem2];
                    }
                    sg[i] = tem1;
                    sg[j] = tem2;
                }
            }
        }
    }
    return ans;
}
// 将找到的路径存储
void AddPath(int cn)
{
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= cn; i++)
    {
        if (!vis[sg[i]])
        {
            vis[sg[i]] = 1;
            vis[cont[i]] = 1;
            while (p[sg[i]][cont[i]])
            {
                int sss = cont[i];
                cont[i] = p[sg[i]][cont[i]];
                matrix[sss][cont[i]]++;
                matrix[cont[i]][sss]++;
            }
            matrix[sg[i]][cont[i]]++;
            matrix[cont[i]][sg[i]]++;
        }
    }
}
// 输出路径
void Print_Path()
{
    printf("top=%d\n", top);
    for (int i = top - 1; i >= 0; i--)
    {
        printf("%d", path[i]);
        if (i)
            printf("->");
    }
    puts("");
}
//初始化各边信息
void Inif()
{
    for (int i = 0; i <= N; i++)
    {
        for (int j = 0; j <= N; j++)
        {
            mapp[i][j] = (i == j) ? 0 : inf;
        }
    }
}
// 中国邮路信息建立
void CNLoad()
{
    while (~scanf("%d%d", &n, &m))
    {
        Inif();
        int i, beg, sum = 0; // sum用来计算路径长度
        memset(matrix, 0, sizeof(matrix));
        memset(d, 0, sizeof(d));
        memset(sg, 0, sizeof(sg));
        memset(path, 0, sizeof(path));
        memset(p, 0, sizeof(p));
        memset(cont, 0, sizeof(cont));
        // 存储各边信息
        for (i = 1; i <= m; i++)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            d[a]++;
            d[b]++;
            matrix[a][b] = 1;
            matrix[b][a] = 1;
            mapp[a][b] = c;
            mapp[b][a] = c;
            gg[i].v = a;
            gg[i].u = b;
            gg[i].cost = c;
            sum += c;
        }
        beg = 1;
        int cnt = 0;
        for (i = 1; i <= n; i++)
        {
            if (d[i] & 1)
            {
                cnt++;
                sg[cnt] = i;
                beg = i;
            }
        }
        if (!cnt)
        {
            printf("sum=%d\n", sum);
            Fleury(beg);
            Print_Path();
        }
        else
        {
            Floyed();
            printf("sum=%d\n", sum + ADD(cnt));
            AddPath(cnt);
            Fleury(beg);
            Print_Path();
        }
    }
}
int main()
{
    CNLoad();
    return 0;
}

测试用例:(图结构)

输出结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1915442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「媒体邀约」上海请媒体的费用

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 上海无疑是最具活动的城市之一&#xff0c;各种大大小小的论坛、发布会、展览展会应接不暇&#xff0c;那么在上海做活动想邀请媒体进行宣传报道&#xff0c;需要多少费用呢&#xff1a;…

Outlook邮件提醒通知功能详解:设置教程!

Outlook邮件提醒通知使用指南&#xff1f;如何个性设计邮件通知&#xff1f; 为了帮助用户更好地管理邮件&#xff0c;Outlook提供了强大的邮件提醒通知功能。AokSend将详细介绍如何设置和使用Outlook邮件提醒通知功能&#xff0c;以提高工作效率和管理时间的能力。 Outlook邮…

昇思25天学习打卡营第12天|应用实践之基于MindSpore通过GPT实现情感分类

基本介绍 今天的应用实践是基于MindSpore通过GPT实现情感分类&#xff0c;这与之前的使用BERT模型实现情绪分类有异曲同工之妙&#xff0c;本次使用的模型是OpenAI开源的GPT&#xff0c;数据集是MindNLP内置的数据集imdb。我们将会使用该数据集对GPT进行训练&#xff0c;然后进…

鲁棒控制器设计方法:systune,hinfsyn,musyn,slTuner

systune和hinfsyn更侧重于基于数学模型的控制器设计&#xff0c;而musyn则特别考虑了系统的不确定性。slTuner则提供了在Simulink环境中进行控制器设计和调整的能力。 指定结构的控制器整定&#xff1a;systune, hinfstruct广义控制对象整定&#xff1a;musyn, mixed musyn, h…

LabVIEW自动测控与故障识别系统

使用LabVIEW 2019在Win10 64位系统上开发自动测控软件&#xff0c;通过与基恩士NR-X100数据采集仪通讯&#xff0c;实时采集和分析数据&#xff0c;自动识别判断产品是否合格&#xff0c;并增加数据记录和仿真功能。 具体解决方案&#xff1a; 1. 系统架构设计 硬件接口&#…

设计模式之工厂模式(简单工厂、工厂方法、抽象工厂)

写在前面&#xff1a;本文是个人在学习设计模式时的所思所想&#xff0c;汇总了其他博主及自己的感悟思考&#xff0c;可能存在出入&#xff0c;请大家理性食用~~ 工厂模式 在工厂模式中&#xff0c;父类决定实例的生成方式&#xff0c;但并不决定所要生成的具体的类&#xf…

带你了解“Java新特性——模块化”

Java平台从Java 8向Java 9及更高版本的进化&#xff0c;其中引入了一个重要的新特性——模块系统&#xff08;Project Jigsaw&#xff09;。模块系统的目的是解决大型应用的依赖管理问题&#xff0c;提升性能&#xff0c;简化JRE&#xff0c;增强兼容性和安全性&#xff0c;并提…

求整数数组的子集【C语言】

方法1&#xff1a;通过二进制位&#xff0c;因为n个整数数组的子集有2的n次方个&#xff0c;例如整数数组为{1,2,3},子集有2的3次方&#xff0c;8个&#xff1b; 期望的输出形式 其中需要了解关注的是 n&1判断最低位是否有数。如果一个子集为{2}&#xff0c;利用二进制位…

C++初阶:类与对象(一)

✨✨所属专栏&#xff1a;C✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 类的定义 定义格式 • class为定义类的关键字&#xff0c;后面跟类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员&#xff1b;类中的变量称为类的…

2024最新PyCharm下载安装

&#xff08;1&#xff09;打开官网&#xff1a;https://www.jetbrains.com/ &#xff08;2&#xff09;点击pycharm &#xff08;3&#xff09;进入后点击下载按钮 &#xff08;4&#xff09;此时有两个选择&#xff1a;有专业版和社区版 PyCharm有专业版&#xff08;Prof…

zynq启动和程序固化流程

普通FPGA启动 FPGA的启动方式主要包含主动模式、被动模式和JTAG模式。 主动模式&#xff08;AS模式&#xff09; 当FPGA器件上电时&#xff0c;它作为控制器从配置器件EPCS中主动发出读取数据信号&#xff0c;并将EPCS的数据读入到自身中&#xff0c;实现对FPGA的编程。这种…

公众号运营秘籍:8 大策略让你的粉丝翻倍!

在当今信息爆炸的时代&#xff0c;微信公众号的运营者们面临着前所未有的挑战&#xff1a;如何在这个充满竞争的红海中脱颖而出&#xff0c;吸引并留住粉丝&#xff1f;事实上&#xff0c;微信公众号的红利期并未完全过去&#xff0c;关键在于我们如何策略性地运营&#xff0c;…

关于复现StableDiffusion相关项目时踩坑的记录

研究文生图也有了一段时间&#xff0c;复现的论文也算是不少&#xff0c;这篇博客主要记录我自己踩的坑。 目前实现文生图的项目主要分为两类&#xff1a; 一、基于Stable-diffusion原项目文件实现 原项目地址&#xff1a;https://github.com/Stability-AI/stablediffusion …

【自监督学习】DINO in ICCV 2021

一、引言 论文&#xff1a; DINO: Emerging Properties in Self-Supervised Vision Transformers 作者&#xff1a; Facebook AI Research 代码&#xff1a; DINO 特点&#xff1a; 对于一张图片&#xff0c;该方法首先进行全局和局部的裁剪与增强并分别送入教师和学生网络&am…

YOLOv10改进 | 图像去雾 | MB-TaylorFormer改善YOLOv10高分辨率和图像去雾检测(ICCV,全网独家首发)

一、本文介绍 本文给大家带来的改进机制是图像去雾MB-TaylorFormer&#xff0c;其发布于2023年的国际计算机视觉会议&#xff08;ICCV&#xff09;上&#xff0c;可以算是一遍比较权威的图像去雾网络&#xff0c; MB-TaylorFormer是一种为图像去雾设计的多分支高效Transformer…

WordPress PHP Everywhere <= 2.0.3 远程代码执行漏洞(CVE-2022-24663)

前言 CVE-2022-24663 是一个影响 WordPress 插件 PHP Everywhere 的远程代码执行&#xff08;RCE&#xff09;漏洞。PHP Everywhere 插件允许管理员在页面、文章、侧边栏或任何 Gutenberg 块中插入 PHP 代码&#xff0c;以显示基于评估的 PHP 表达式的动态内容。然而&#xff…

FreeCAD: 将STL格式文件转换为step格式文件的记录

首先我们需要下载开源的FreeCAD软件&#xff0c;官网链接如下&#xff1a; FreeCAD: Your own 3D parametric modeler 傻瓜式安装&#xff0c;跳过~ FreeCAD 是一款免费的开源CAD软件&#xff0c;支持多种文件格式转换&#xff0c;包括STL到STEP。 步骤&#xff1a; 打开Free…

PTrade常见问题系列7

获取可转债数据为空。 量化交易内&#xff0c;获取可转债标的行情&#xff0c;提示报错12319*.SZ不支持。 1、建议客户在研究内执行get_price&#xff0c;返回无数据&#xff1b; 2、怀疑asset.pk内不存在该可转债代码&#xff0c;再研究内执行import pandas as pd df pd.re…

前端使用pinia中存入的值

导入pinia,创建pinia实例 使用pinia中的值

Rust: 高性能序列化库Fury PK bincode

在序列化库中&#xff0c;传统的有Json,XML&#xff0c;性能好的有thrift&#xff0c;protobuf等。 对于二进制库来讲&#xff0c;据Fury官网的介绍&#xff0c;Fury性能要远远好于protobuf&#xff0c;且不象protobuf还需要定义IDL(即写.proto文件)&#xff0c;非常轻便&#…