一本通 一笔画问题 洛谷P1636 Einstein学画画

P1636 Einstein学画画

相信大家都玩过一笔画这种游戏吧,这其实算得上是我们能够接触到的比较常见的数学问题,有一个很知名的就是七桥问题

这个问题包括所有的一笔画问题都是在欧拉回路的涵盖范围内的,那么欧拉回路又是什么呢?

我们把一个这个桥化为无向图进行这样一个分析,除了起点以外,每一次当一个人由一座桥进入一块陆地(或点)时,他同时也由另一座桥离开此点。所以每行经一点时,计算两条边,从起点离开的线与最后回到始点的线亦计算两座桥,因此每一个陆地与其他陆地连接的桥数必为偶数。

读不懂没关系,多读几遍慢慢理解,我们把这个化简一下,就成了

对于无向图:

  存在欧拉回路的条件:每个点的度都为偶数;

  存在欧拉路的条件:有且只有两个点的度为一,且这两个点分别为起点和终点;

对于有向图:

  存在欧拉回路的条件:每个点出度等于入度;

  存在欧拉路的条件:存在一个点出度比入度多一作为起点,存在一点入度比出度多一作为终点,其余点出度等于入度;

你还觉得麻烦是吗,再化简一下

如果一个图能一笔画,那么叫做欧拉图,如果这个图最后能回到起点,那么叫做欧拉回路

定理一:存在欧拉路的条件:图是联通的,且只有2个奇点

定理二:存在欧拉回路的条件:图是联通的,且有0个奇点

那么我们看这个题,他其实就是考差了一个对图上所有点的遍历,我们把所有点进行遍历,把所有与其相连的边进行遍历,遍历完一个点之后,如果是奇点就加到计数器当中去,来看代码吧

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
int n, m, graph[1000][1000], x, y,_count,sum;
int main()
{    
    memset(graph, 0, sizeof(graph));
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d%d", &x, &y);
        graph[x][y] = graph[y][x] = 1;
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (graph[i][j] == 1)
                _count++;
        }
        if(_count%2) sum++;
        _count=0;
    }
    if(sum==0)
    cout<<1;
    else cout<<ceil(sum/2.0);
    return 0;
}
/*
这道题就是一个简单的欧拉回路的模板,统计每个点的度数,如果每个点的度数都为偶数,那么就可以一笔画(因为每个点都有进有出)
否则统计度数为奇数的点的个数(记为num)
答案就是num/2(每次都把度数为奇数的点分别作为起点和终点)。
*/
原文地址:https://www.cnblogs.com/this-is-M/p/10745239.html