Play on Words (判断是否有有向欧拉路或半欧拉路)

本文介绍了一种简化版Catenyms算法的实现方法,通过使用并查集来判断一组字符串是否能构成有效的字母顺序。文章提供了完整的代码示例,并解释了如何通过调整数据结构来优化算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

就是Catenyms的简略版,只是无需保存路径。

题目:

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int fa[26+5];          //并查集
int in[26+5],out[26+5];//入度,出度
bool mark[26+5];       //mark[i]=true,表i这个字母被用到作为图顶点了
int m;//单词数,即边数

int findset(int u)
{
    if(fa[u]==-1) return u;
    return fa[u]=findset(fa[u]);
}
bool ok()//判断是否弱连通图
{
    int k=0;
    for(int i=0;i<26;i++)if(mark[i])
        if(findset(i)==i) k++;
    return k==1;
}
void init()
{
    memset(fa,-1,sizeof(fa));
    memset(mark,0,sizeof(mark));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
}
int main()
{
    int n;

    string str[100010];
    int T;
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
           cin>>str[i];
           int u,v;
            u=str[i][0]-'a';
            int yyy=str[i].length()-1;
            v=str[i][yyy]-'a';//表示该边还未被访问
            mark[u]=mark[v]=true;
            in[v]++, out[u]++;
            u=findset(u), v=findset(v);
            if(u!=v) fa[u]=v;       //合并连通分量
        }
        int i,c1=0,c2=0;                //错误1,这里c1与c2忘了初始化
        for(i=0;i<26;i++)if(mark[i])
        {
            if(in[i]==out[i]) continue;
            else if(in[i]-out[i]==1) c1++;
            else if(out[i]-in[i]==1) c2++;
            else break;
        }
        if(i==26&&((c1==c2&&c1==0)||(c1==c2&&c1==1)) && ok() )//所有点度符合要求且弱连通
        {

            printf("Ordering is possible.\n");
        }
        else printf("The door cannot be opened.\n");
    }
    return 0;
}


### 如何判断是否存在欧拉路 在图论中,欧拉路是指通过图中每条边恰好一次的径。对于无向图和有向图,存在不同的条件来判断是否可以找到一条欧拉路。 #### 无向图中的欧拉路判定 在一个连通的无向图中,如果满足以下条件,则该图存在欧拉路: - 至多有两个顶点的度数为奇数[^1]。 - 如果恰有两个顶点的度数为奇数,则这两个顶点分别是欧拉路的起点和终点。 - 如果所有顶点的度数均为偶数,则任意一点都可以作为欧拉路的起点和终点,此时欧拉路即为欧拉。 以下是基于上述理论的一个简单 Python 实现: ```python from collections import defaultdict, deque def is_eulerian_path_undirected(graph): odd_degree_count = sum(1 for node in graph if len(graph[node]) % 2 != 0) connected_components = get_connected_components(graph) # Check connectivity and degree conditions if len(connected_components) > 1 or odd_degree_count not in {0, 2}: return False return True def get_connected_components(graph): visited = set() components = [] def dfs(node, component): stack = [node] while stack: current = stack.pop() if current not in visited: visited.add(current) component.append(current) stack.extend(neigh for neigh in graph[current] if neigh not in visited) for node in graph: if node not in visited: component = [] dfs(node, component) components.append(component) return components ``` #### 有向图中的欧拉路判定 对于有向图,要判断是否存在欧拉路,需满足以下条件之一: - 存在唯一一个顶点 \( u \),使得它的出度比入度大 1; - 存在唯一一个顶点 \( v \),使得它的入度比出度大 1; - 所有其他顶点的入度等于出度[^3][^4]。 下面是针对有向图的实现代码片段: ```python def is_eulerian_path_directed(graph): indegree = defaultdict(int) outdegree = defaultdict(int) for node in graph: outdegree[node] += len(graph[node]) for neighbor in graph[node]: indegree[neighbor] += 1 start_nodes = 0 end_nodes = 0 for node in set(list(indegree.keys()) + list(outdegree.keys())): diff = outdegree[node] - indegree[node] if abs(diff) > 1: return False elif diff == 1: start_nodes += 1 elif diff == -1: end_nodes += 1 if start_nodes not in {0, 1} or end_nodes not in {0, 1}: return False weakly_connected_components = get_weakly_connected_components(graph) return len(weakly_connected_components) == 1 def get_weakly_connected_components(graph): undirected_graph = defaultdict(set) for node in graph: for neighbor in graph[node]: undirected_graph[node].add(neighbor) undirected_graph[neighbor].add(node) return get_connected_components(undirected_graph) ``` 以上两个函数分别实现了对无向图和有向图是否存在欧拉路判断逻辑。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值