Loading

欧拉回路

七桥问题

看上面的无向图,七桥问题就是存不存在一条道路,能够完整地不重复的走完这些边。

欧拉回路和欧拉路径

欧拉路径就是满足上面问题的一个通路,如果这个通路还是一个回路,称为欧拉回路。

首先,不管图是什么样的,要满足欧拉回路,首先图得是连通图,这是基本条件,本篇默认所有图都是连通的,包括应用题中的输入数据也一定是连通图。

无向图

对于无向图,因为每条边只能经过一次,所以如果想得到欧拉回路,必须满足节点连接的边是偶数个。可以在纸上画一下。

而对于欧拉路径,它也有可能是欧拉回路,也有可能不是,如果不是的话,起点和终点连接的边是奇数。

所以

  • 欧拉回路:图中所有节点的度是偶数
  • 欧拉路径:图中奇数度的节点为0个或2个

有向图

对于有向图,如果想得到欧拉回路,那么每个节点的入度必定等于出度。

如果是欧拉路径,则有一个节点的入度比出度小1,这个节点是起点,有一个节点的出度比入度小1,这个节点是终点。

  • 欧拉路径:图中所有节点入度等于出度
  • 欧拉回路:图中只有一个节点入度比出度小1,也只有一个节点入度比出度大1,剩下的入度等于出度

应用

输入n(n≤100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如acm、malform、mouse)。每个单词最多包含1000个小写字母。输入中可以有重复单词。

把单词看作边,字母看作节点,那么acm这个单词就表示字母a的入度加一,字母m的出度加一。

然后只需要按上面的判断方式判断即可。

PS: 该程序并未判断图的连通性

#include "iostream"
#include "cstdio"
#include "string"
#define MAX 10000


using namespace std;

int in[26],out[26];

int main() {
    string word;
    while (cin >> word && word!="#") {
        in[word[0] - 'a']++;
        out[word[word.length() - 1] - 'a']++;
    }
    int a=0, b=0;
    for (int i = 0; i < 26; i++) {
        if (in[i] != out[i]) {
            if (in[i] + 1 == out[i])a++; // 可能是起点,因为起点入度可能小1
            else if (in[i] == out[i] + 1)b++; // 可能是终点,因为终点出度可能小1
            else {
                printf("Faild!");
                return 0;
            }
        }
    }
    if (a && b && a + b > 2) {
        printf("Faild!");
        return 0;
    }
    printf("OK");
    return 0;
}

参考

posted @ 2020-11-09 20:35  yudoge  阅读(488)  评论(0编辑  收藏  举报