信息学奥赛一本通 1341:【例题】一笔画问题

news/2024/7/15 18:37:01 标签: 算法, 图论

【题目链接】

ybt 1341:【例题】一笔画问题

【题目考点】

1. 图论:欧拉回路

求解欧拉回路使用Hierholzer算法
复杂度: O ( V + E ) O(V+E) O(V+E)

【解题思路】

  • 无向图有欧拉回路的条件:所有顶点的度都是偶数。
  • 无向图有欧拉路径的条件:有两个顶点的度是奇数,其余顶点的度都是偶数。

该题默认一定有欧拉路径或欧拉回路。
遍历选择起始顶点,如果v的度为奇数,那么选择该顶点为起始顶点。否则起始顶点默认为1号顶点。
使用Hierholzer算法可以在 O ( V + E ) O(V+E) O(V+E)的时间复杂度内求出欧拉回路。
顶点数n最大为100,可以使用邻接矩阵或邻接表解决。

【题解代码】

解法1:邻接矩阵

#include<bits/stdc++.h>
using namespace std;
#define N 105
int n, m, edge[N][N], deg[N];//n:顶点数 m:边数 deg[i]:顶点i的度 
stack<int> stk;
void dfs(int u)//Hierholzer算法 
{
    for(int v = 1; v <= n; ++v)
    {
        if(edge[u][v])
        {
            edge[u][v] = edge[v][u] = 0;
            dfs(v);        
        }
    }
    stk.push(u);
}
int main()
{
    int st = 1, f, t;//st:起点 
    cin >> n >> m;
    for(int i = 1; i <= m; ++i)
    {
        cin >> f >> t;
        edge[f][t] = edge[t][f] = 1;
        deg[f]++, deg[t]++;
    }
    for(int v = 1; v <= n; ++v)//如果找到奇数度顶点,就从奇数度顶点出发,否则从1出发 
    {
        if(deg[v] % 2 == 1)
        {
            st = v;
            break;
        }
    }
    dfs(st);
    while(stk.empty() == false)
    {
        cout << stk.top() << ' ';
        stk.pop();
    }
    return 0;
}

解法2:邻接表

#include<bits/stdc++.h>
using namespace std;
#define N 105
#define M 2005
struct Node
{
	int v, e;//v:顶点编号 e:边的编号 
	Node(){}
	Node(int a, int b):v(a), e(b){}
};
int n, m, deg[N], beg[N];//n:顶点数 m:边数 deg[i]:顶点i的度 beg[i]:顶点i的邻接点从edge[beg[i]]开始算起,前面的相当于删掉了。 
vector<Node> edge[N];
bool vis[M];
stack<int> stk;
void dfs(int u)//Hierholzer算法 
{
	for(int &i = beg[u]; i < edge[u].size(); ++i)//i是beg[u]的引用,++i相当于++beg[u],这样在下一次访问顶点u的邻接点时,只需要从下标beg[u]开始看起,前面的当做已经被删掉了
	{
		int v = edge[u][i].v, e = edge[u][i].e;
		if(vis[e] == false)
		{
			vis[e] = true;
			dfs(v);
		}
	}
    stk.push(u);
}
int main()
{
    int st = 1, f, t;//st:起点 
    cin >> n >> m;
    for(int i = 1; i <= m; ++i)
    {
        cin >> f >> t;
        edge[f].push_back(Node(t, i));
        edge[t].push_back(Node(f, i));
        deg[f]++, deg[t]++;
    }
    for(int v = 1; v <= n; ++v)//如果找到奇数度顶点,就从奇数度顶点出发,否则从1出发 
    {
        if(deg[v] % 2 == 1)
        {
            st = v;
            break;
        }
    }
    dfs(st);
    while(stk.empty() == false)
    {
        cout << stk.top() << ' ';
        stk.pop();
    }
    return 0;
}

http://www.niftyadmin.cn/n/181308.html

相关文章

JetBrains GoLand 2022.3 Crack

GoLand 2022.3 提供性能增强&#xff0c; 以及泛型和 Go 工作区的新功能。 我们集成了 Go Playground&#xff0c;添加了对改进 Go 文档评论的支持&#xff0c; 引入了 HTTP 客户端和 Docker 的新功能&#xff0c; 并使新 UI 可用。 像往常一样&#xff0c;您会发现Web开发和数…

正则表达式详解(零基础教学,手把手教你写正则)

本篇文章将从零讲解什么是正则表达式&#xff0c;以及正则表达式的规则、在python中的应用&#xff0c;用通俗易懂的描述方式进行零基础级别的讲解&#xff0c;尽量做到全网最全讲解&#xff0c;力求最高质量文章&#xff0c;欢迎关注&#xff01;点击目录可直接进行相关位置跳…

「解析」牛客网-华为机考企业真题61-80

又是一年春招时&#xff0c;有幸收到华为自动驾驶算法岗&#xff0c;之前刷题不多&#xff0c;在此汇总下牛客网的真题&#xff0c;主要采用Python编写&#xff0c;个人觉得语言只是实现工具而已&#xff0c;并不是很关键&#xff0c;Python简洁易懂&#xff0c;更加适合算法工…

高压放大器在工作中的应用实例有哪些

高压放大器使用领域广泛&#xff0c;科学研究、教学、产品研发等各个领域。 高压放大器基于超声波控制细胞生长 在生物领域中&#xff0c;细胞在不同的频率、功率、作用时间和占空比等参数的超声波生长装置&#xff0c;存活率、生长时间等都有所变化。因此所需的频率、幅值的波…

Go语言精修(尚硅谷笔记)第十章

十、面向对象编程 10.1 go面向对象编程说明 1 ) Golang也支持面向对象编程(OOP)&#xff0c;但是和传统的面向对象编程有区别&#xff0c;并不是纯粹的面向对象语言。所以我们说Golang支持面向对象编程特性是比较准确的。 2 ) Golang没有类(class)&#xff0c;Go语言的结构体…

网络安全 2023 年为什么如此吃香?事实原来是这样....

前言由于我国网络安全起步晚&#xff0c;所以现在网络安全工程师十分紧缺。俗话说:没有网络安全就没有国家安全为什么选择网络安全&#xff1f;十四五发展规划建议明确提出建设网络强国&#xff0c;全面加强网络安全保障体系和能力建设&#xff0c;加强网络文明建设&#xff0c…

【Vue3源码Runtime-core篇】 第二章初始化Component

第二章初始化Component 前言 上一篇文章讲了整个runtime-core包的核心逻辑&#xff0c;以及patch算法流程图 流程图: render函数内patch算法初始化组件和Element的流程&#xff0c;这一章就开始实现整个流程&#xff0c;我们只要按着流程去创建函数就可以了。 案例 今天项目…

python调用CC++

python调用C程序 一般来说在python调用C/C程序主要可以分为3步&#xff1a; 1、编写C/C实现程序。2、将C/C程序编译成动态库。-3、在Python中调用编译生成的库。Python在调用C/C程序时有一些不同&#xff0c;需要注意。 Python调用C语言程序比较简单&#xff0c;将C语言程序…