uva10054 The Necklace (欧拉回路路径输出 (并查集 + DFS) || (DFS + stack))

题意: 用50种珠子, 每种珠子两头颜色不同, 当两个珠子的有一头颜色相同时, 这一头可以连起来。 给点一些珠子, 看能否连成项链

思路:其实就是欧拉回路(项链)。 用并查集判断图的连通性 + 判断度数合法性, 图就存在。 然后用DFS输出路径。

又想到一种。二维数组G不再表示G[u][v] u v之间边的存在性, 而是表示边数。 这样只要走一条减一条, 统计走过的条数,最后等于edge, 则图就连通了。走的时候把路径u v压入path栈。 代码在最下面。

算法复杂度:


代码:

#include <cstdio>
#include <cstring>
using namespace std;

#define MAX_N 55 

int deg[MAX_N];
int father[MAX_N];
int G[MAX_N][MAX_N];
int edge, vertex;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是用C语言实现欧拉图的判定并输出所有欧拉图的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAXN 100 // 最大顶点数 int graph[MAXN][MAXN]; // 图的邻接矩阵 int degree[MAXN]; // 各顶点的度数 int n; // 顶点数 void dfs(int u, int* euler, int* cnt) { for (int v = 0; v < n; v++) { if (graph[u][v]) { // 存在从u到v的边 graph[u][v] = graph[v][u] = 0; // 将该边删除 dfs(v, euler, cnt); // 递归访问v } } euler[(*cnt)++] = u; // 将u加入欧拉回路序列 } void euler_dfs() { int euler[MAXN]; // 存储欧拉回路的顶点序列 int cnt = 0; // 当前欧拉回路序列中的顶点数 dfs(0, euler, &cnt); // 从顶点0开始遍历 printf("欧拉回路序列为:\n"); for (int i = cnt - 1; i >= 0; i--) { printf("%d ", euler[i]); // 输出欧拉回路序列 } printf("\n"); } int is_euler_graph() { for (int i = 0; i < n; i++) { if (degree[i] % 2 != 0) { // 存在度数为奇数的顶点 return 0; // 不是欧拉图 } } euler_dfs(); // 输出所有欧拉回路 return 1; // 是欧拉图 } int main() { printf("请输入图的顶点数和边数:\n"); scanf("%d", &n); int m; scanf("%d", &m); printf("请输入各边的两个端点:\n"); for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); graph[u][v] = graph[v][u] = 1; // 添加无向边 degree[u]++; // 更新各顶点的度数 degree[v]++; } if (is_euler_graph()) { printf("该图是欧拉图!\n"); } else { printf("该图不是欧拉图!\n"); } return 0; } ``` 在这个示例代码中,我们用邻接矩阵存储无向图,并用degree数组记录各顶点的度数。在判断图是否为欧拉图时,我们首先遍历各顶点,如果有度数为奇数的顶点,则不是欧拉图;否则,我们调用euler_dfs函数输出所有欧拉回路。在euler_dfs函数中,我们从任意一个顶点开始进行DFS遍历,并在访问每条边时将其删除,同时将经过的顶点加入欧拉回路序列中。最后,我们将欧拉回路序列倒序输出即可。 希望这个示例代码能够帮助你理解如何用C语言实现欧拉图的判定和输出所有欧拉图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值