欧拉路径的存在条件
有限图 G 是链或圈的充要条件是:G为连通图,且其中奇顶点的数目等于0或者2。有限连通图 G 是圈当且仅当它没有奇顶点。
链就是存在欧拉路径,圈就是存在欧拉回路。
这个都比较好判断
再插一下什么是割边
割边就是一条边,去掉他之后整个图由连通变成不连通了。就像桥一样。
下面来求一下欧拉路径
据说是用弗洛莱算法。
#include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; /* 弗罗莱算法 */ int stk[1005]; //记录路径的栈 int top; //栈指针 int N, M, ss, tt; int mp[1005][1005]; void dfs(int x) { stk[top++] = x; for (int i = 1; i <= N; ++i) { if (mp[x][i]) { mp[x][i] = mp[i][x] = 0; // 删除此边 dfs(i); break; } } } void fleury(int ss) { int brige; top = 0; stk[top++] = ss; // 将起点放入Euler路径中 while (top > 0) { brige = 1; for (int i = 1; i <= N; ++i) { // 试图搜索一条边不是割边(桥) if (mp[stk[top-1]][i]) { brige = 0; break; } } if (brige) { // 如果没有点可以扩展,输出并出栈 printf("%d ", stk[--top]); } else { // 否则继续搜索欧拉路径 dfs(stk[--top]); } } } int main() { int x, y, deg, num; while (scanf("%d %d", &N, &M) != EOF) { memset(mp, 0, sizeof (mp)); for (int i = 0; i < M; ++i) { scanf("%d %d", &x, &y); mp[x][y] = mp[y][x] = 1; } //map用来存储边与边之间的连接信息,M是边树啊 for (int i = 1; i <= N; ++i) { //算n个点的度数 deg = num = 0; for (int j = 1; j <= N; ++j) { deg += mp[i][j]; } if (deg % 2 == 1) { ss = i, ++num; printf("%d\n", i); } } if (num == 0 || num == 2) { fleury(ss); } else { puts("No Euler path"); } } return 0; } 测试用例:
/* 9 12 1 5 1 9 5 3 5 4 5 8 2 3 2 4 4 6 6 7 6 8 7 8 8 9 path: 4 5 8 7 6 8 9 1 5 3 2 4 6 */
时间: 2024-11-09 11:14:35