首页 > 其他分享 >一笔画问题

一笔画问题

时间:2024-11-21 18:30:02浏览次数:1  
标签:笔画 int dfs 问题 maxn 奇点 欧拉

柯尼斯堡七桥问题

18世纪时,欧洲的一个小城柯尼斯堡有七座桥,连接了四个地方,如下图所示。人们聊天时,有人提出这样一个问题:是否存在一种方法,能够从一个地点出发,经过每座桥一次且仅一次,最后回到起点。人们讨论了很长时间,都没有找到方案。
image

欧拉出手

这个问题引起了欧拉的兴趣。他稍微研究了以下,很快就证明了该问题是无解的。即不存在一种走法,能够从某个地点出发,经过每座桥一次且仅一次,最后回到起点。
欧拉是如何思考这个问题的呢?

首先,他简化了一下。将四块陆地看做四个点,将七座桥看做是七条边,得到如下的图:

现在只需要在A、B、C、D四点中选一个点为起点,一笔画完该图,最后回到起点。

我们发现,如果存在这样一条线路,那么与每个点相连接的边一定是偶数条。
这很显然,因为对于起点而言,一定是先出后进,而对于其他点,一定是先进后出。每条边只能走一次。这就要求与该点相连的边必须是偶数条。
而上图不符合这个条件,所以他是无解的。

我们用度来表示一个点相连的边数。如果一个点的度为偶数,则称为偶点;否则称为奇点。

欧拉不仅解决了七桥问题,还得出了一个结论,开创了人类对图论的研究。

  • 如果所有的点都是偶点,则该图可以一笔画完,并回到起点。
  • 如果仅存在两个奇点,则可以从一个奇点出发,一笔画完,最终到达另一个奇点。
  • 其他情况,图不能一笔画完

人们把能够一笔画完并回到起点的图,称为欧拉回路;把能够一笔画完,但不能回到起点的图,称为欧拉通路。

一笔画问题

我们已经知道如何判断一个图是不是欧拉回路或者欧拉通路。
如果是欧拉回路或者欧拉通路,如何输出一种一笔画完的方案呢?
这样的方案可能有多种,我们只需要输出任意一种即可。

可以使用dfs,走过的边马上删掉, 如果一个点的边都删完了,则将该点加入到一个序列。dfs结束后,该序列即为一笔画的路径。

void dfs(int s){
    vis[s] = 1;
    for(int i = 1; i <= n; i++){
        if(arr[s][i]){
            arr[s][i] = arr[i][s] = 0;
            dfs(i);
        }
    }
    path[top++] = s;
}

这是一个简单而神奇的算法。它有点类似于树的后序序列
但改为先序序列就不对了。这很好理解。因为来到分叉口,如果选择一条错误的路,那么有些分支就永远错过了。后面虽然递归返回时能够我们重新光顾这个岔路口,但是在路径上不是连续的。

而改成后序序列后,在任何一个分岔路口,不管选择那一条走,后序序列都能够保证最后回到这个岔路口。等到所有的岔路口都走了并返回后,再来时的路返回,这样路径就接上了。
比如有一条边\((i,j)\),现在从\(i\)走到了\(j\),那么返回时能够保证\(j\)的所有其他岔路都走了并且返回了以后,再返回到\(i\)点。

例题1:

对给定的一个无向图,判断能否一笔画出。若能,输出一笔画的先后顺序,否则输出“No Solution!”
所谓一笔画出,即每条边仅走一次,每个顶点可以多次经过。
输出字典序最小的一笔画顺序。

分析:首先判断是不是一笔画的图?如果有0个奇点或者2个奇点,则可以一笔画,否则直接输出"No Solution!".

如何保证字典序最小呢?
因为我们是后序遍历,先访问的点,实际上是后进入队列的。所以, 我们按照编号由小到大的顺序依次dfs,最后将队列逆序输出即可。
如果全为偶点,我们以\(1\)号点为起点;如果有两个奇点,则从编号较小的奇点做dfs。

#include <bits/stdc++.h>
using namespace std;
#define maxn 105
int arr[maxn][maxn];
int n, m, top, du[maxn];
int odds, start;
bool noans;
int path[maxn * maxn];
bool vis[maxn];
int ecnt;
int visit;
void dfs(int s){
    vis[s] = 1;
    for(int i = 1; i <= n; i++){
        if(arr[s][i]){
            arr[s][i] = arr[i][s] = 0;
            dfs(i);
        }
    }
    path[top++] = s;
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            scanf("%d", &arr[i][j]);
            if(arr[i][j] == 1) du[i]++, ecnt++;
        }
    }
    ecnt /= 2;
    for(int i = n; i > 0; i--){
        if(du[i] % 2 == 1) {
            odds++;
            start = i;
        }
    }
    if(odds == 0){   
            dfs(1);
        }
    else if(odds == 2){
        dfs(start);
    }
    else noans = 1; 
    if(noans == 1 || top != ecnt + 1)printf("No Solution!\n");
    else {
        for(int i = top - 1; i >= 0; i--){
            printf("%d ", path[i]);
        }
    }
    return 0;
}

例题二

题目描述:

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

分析

将52个字母看做52个点,如果出现一个字母对,则将对应的两个点连一条无向边。
判断是否是欧拉回路,输出一笔画的顺序即可。

标签:笔画,int,dfs,问题,maxn,奇点,欧拉
From: https://www.cnblogs.com/hefenghhhh/p/18561047

相关文章

  • 【Flinkcdc问题解决】java.lang.NoClassDefFoundError: org/apache/flink/shaded/guav
    1.环境介绍Flink1.17+Flinkcdc2.2.12.问题描述使用Flink1.17和Flinkcdc2.2.1环境进行数据加工,但是报以上错误,原因是版本不匹配,flinkcdc2.2.1用的是guava18,但是flink1.17用的是guava30,导致冲突。3.问题解决添加flink-sql-connector-mysql-cdc依赖<dependen......
  • 解决viedo标签无法自动播放的问题
    解决viedo标签无法自动播放的问题问题描述:使用了<viedo>标签,也加上了autoplay属性,但是在打开页面的时候还是不能实现音频自动播放。还使用了<audio>标签加入autoplay属性,也不能实现。同时还尝试了<iframe>标签,加上了allow=autoplay,同样也不能实现。解决办法:1.了......
  • 【linux之clickhouse的问题记录】记由于clickhouse服务内存打满导致cpu/mem都飙升然后
    在记录相关文档的过程中发现监控中关于该节点的clickhouse数据异常,随后在node节点监控中也不见该节点信息于是找到相关机器进行检查,堡垒机发现无法连接clickhouse的节点,随后找同网段的机器尝试ping一下测试连通性,随后发现无法ping通错误信息:From172.21.0.1icmp_seq=1Destin......
  • Redis大Key问题如何排查?如何解决?
    Redis大Key是指存储在Redis中的键值对,其中键对应的value占用了较大的内存空间,或者包含了大量的元素。例如,一个存储了数百万个元素的集合(Set)类型的键,或者一个存储了一个很大的字符串(长度可能达到几十MB甚至更大)的键都被认为是大Key。Redis大Key并没有统一的固定标......
  • 去水印小程序downloadFile域名问题解决方式
    ......
  • 视频流媒体播放器EasyPlayer.js无插件直播流媒体音视频播放器Android端webview全屏调
    流媒体播放器的核心技术与发展趋势正在不断推动着行业的变革。未来,随着技术的不断进步和应用场景的不断拓展,流媒体播放器将为用户带来更加便捷、高效、个性化的观看体验。同时,流媒体播放器也会成为数字娱乐产业的重要组成部分,为整个行业的繁荣发展贡献更多的力量。Android端webvi......
  • TSINGSEE青犀新能源充电桩智能管理方案:如何利用AI解决充电难停车难的问题?
    随着新能源汽车产业的迅猛发展,充电桩的安全问题日益凸显,成为制约行业健康发展的重要因素。近年来频发的自燃事件不仅给车主带来了财产损失,也对公众的安全感构成了挑战。因此,利用先进的AI技术和图像识别算法,构建充电桩安全监测体系显得尤为重要。国标GB28181视频平台EasyCVR作为TS......
  • CentOS 7远程连接相关问题
    1、检查网络配置正确。ipaddrshowroute-n2、检查防火墙状态(关闭防火墙)。检查防火墙状态:systemctlstatusfirewalld如果防火墙处于活动状态,允许SSH连接:firewall-cmd--permanent--add-service=ssh重新加载防火墙配置:firewall-cmd--reload3、检查SSH检查SSH服务状态:sy......
  • P2404 自然数的拆分问题
    [#自然数的拆分问题题目描述任何一个大于$1$的自然数$n$,总可以拆分成若干个小于$n$的自然数之和。现在给你一个自然数$n$,要求你求出$n$的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。输入格式......
  • 字节青训-徒步旅行中的补给问题、贪心猫的鱼干大分配
    一、徒步旅行中的补给问题问题描述小R正在计划一次从地点A到地点B的徒步旅行,总路程需要 N 天。为了在旅途中保持充足的能量,小R每天必须消耗1份食物。幸运的是,小R在路途中每天都会经过一个补给站,可以购买食物进行补充。然而,每个补给站的食物每份的价格可能不同,并且小R最多只......