欧拉回路
七桥问题
看上面的无向图,七桥问题就是存不存在一条道路,能够完整地不重复的走完这些边。
欧拉回路和欧拉路径
欧拉路径就是满足上面问题的一个通路,如果这个通路还是一个回路,称为欧拉回路。
首先,不管图是什么样的,要满足欧拉回路,首先图得是连通图,这是基本条件,本篇默认所有图都是连通的,包括应用题中的输入数据也一定是连通图。
无向图
对于无向图,因为每条边只能经过一次,所以如果想得到欧拉回路,必须满足节点连接的边是偶数个
。可以在纸上画一下。
而对于欧拉路径,它也有可能是欧拉回路,也有可能不是,如果不是的话,起点和终点连接的边是奇数。
所以
- 欧拉回路:图中所有节点的度是偶数
- 欧拉路径:图中奇数度的节点为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;
}