POJ2337 欧拉路径字典序输出

本文介绍了一种通过并查集和前向星解决给定单词能否仅使用一次并连接在一起的问题的方法。具体步骤包括将每个单词视为边,记录入度和出度以判断欧拉路径或回路,确保所有节点属于同一连通子集,并通过排序和深度优先搜索找到路径。

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

题意:
      给一些单词,问是否可以每个单词只用一次,然后连接在一起(不一定要成环,能连接在一起就行)。


思路:
      这个题目的入手点比较好想,其实就是问欧拉路径,先说下解题步骤,然后在细说
(1) 把每个单词看成一条边,单词的首字母和尾字母是点
(2) 然后记录入度,出度,根据入度出度判断是不是欧拉路径或者回路
(3) 别往了判断所有点是不是属于同一个连通子集,这个可以用并查集啥的
(4) 把所有的边都排序下,至于是什么顺序,根据自己的存图方式去排
(5) 欧拉路径就从头开始(要是欧拉回路就找个最小的点)深搜找出路径


     之前也没写过输出欧拉路径啥的啊!看有人说可以用栈递归存边,然后就在纸上画了几个8想想,觉得有道理,就自己写了一个欧拉路的(其实很简单),至于排序的地方,我想的是直接在存边之前先把边排序下,因为欧拉路径输出的时候也是比较简单“画6的感觉”,要求字典序最小,因为我用的是前向星,其实这个东西建边是倒叙的,就是a-b a-c a-d 的顺序进去,那么访问的时候是a-d,a-c,a-b这样的,全都是抱着试一试,结果直接a了。虽然是简单题,但是挺高兴啊。


#include<stack>
#include<stdio.h>
#include<string.h>
#include<algorithm>

#define N_node 30
#define N_edge 1000 + 100

using namespace std;

typedef struct
{
    int to ,next;
}STAR;

typedef struct
{
    char str[30];
}EDGE;

STAR E[N_edge];
EDGE edge[N_edge];
int list[N_node] ,tot;
int mer[N_node];
int mark[N_edge];
int deg[N_node];
stack<int>mysk;

bool camp(EDGE a ,EDGE b)
{
    return strcmp(a.str ,b.str) > 0;
}

void add(int a ,int b)
{
    E[++tot].to = b;
    E[tot].next = list[a];
    list[a] = tot;
}

int finds(int x)
{
    return x == mer[x] ? x : mer[x] = finds(mer[x]);
}

void DFS(int s)
{
    for(int k = list[s] ;k ;k = E[k].next)
    {
        if(mark[k]) continue;
        mark[k] = 1;
        DFS(E[k].to);
        mysk.push(k);
    }
}

int main ()
{
    int t ,n ,i ,j;
    int mkc[30];
    scanf("%d" ,&t);
    while(t--)
    {
        scanf("%d" ,&n);
        memset(deg ,0 ,sizeof(deg));
        memset(mkc ,0 ,sizeof(mkc));
        for(i = 1 ;i <= 26 ;i ++)
        mer[i] = i;
        for(i = 1 ;i <= n ;i ++)
        {
            scanf("%s" ,edge[i].str);
            int a = edge[i].str[0] - 'a' + 1;
            int b = edge[i].str[strlen(edge[i].str)-1] - 'a' + 1;
            mer[finds(a)] = finds(b);
            mkc[a] = mkc[b] = 1;
            deg[a] ++;
            deg[b] --;
        }

        int s = 0 ,z = 0 ,f = 0 ,min;
        for(i = 1 ;i <= 26 ;i ++)
        {
            if(mkc[i])
            {
                if(mer[i] == i) s ++;
                if(!deg[i]) continue;
                if(deg[i] == 1)
                z ++ ,min = i;
                else if(deg[i] == -1) f ++;
                else s ++;
            }
        }


        if(s != 1 || f + z != 0 && f + z != 2)
        {
            printf("***\n");
            continue;
        }

        sort(edge + 1 ,edge + n + 1 ,camp);
        memset(list ,0 ,sizeof(list));
        tot = 1;
        for(i = 1 ;i <= n ;i ++)
        {
            int a = edge[i].str[0] - 'a' + 1;
            int b = edge[i].str[strlen(edge[i].str)-1] - 'a' + 1;
            add(a ,b);
        }

        if(z + f == 0) min = edge[n].str[0] - 'a' + 1;

        while(!mysk.empty())
        mysk.pop();
        memset(mark ,0 ,sizeof(mark));
        DFS(min);

        while(!mysk.empty())
        {
            int tou = mysk.top();
            mysk.pop();
            if(mysk.empty())
            printf("%s\n" ,edge[tou-1].str);
            else printf("%s." ,edge[tou-1].str);
        }
    }
    return 0;
}





内容概要:本书《Deep Reinforcement Learning with Guaranteed Performance》探讨了基于李雅普诺夫方法的深度强化学习及其在非线性系统最优控制中的应用。书中提出了一种近似最优自适应控制方法,结合泰勒展开、神经网络、估计器设计及滑模控制思想,解决了不同场景下的跟踪控制问题。该方法不仅保证了性能指标的渐近收敛,还确保了跟踪误差的渐近收敛至零。此外,书中还涉及了执行器饱和、冗余解析等问题,并提出了新的冗余解析方法,验证了所提方法的有效性和优越性。 适合人群:研究生及以上学历的研究人员,特别是从事自适应/最优控制、机器人学和动态神经网络领域的学术界和工业界研究人员。 使用场景及目标:①研究非线性系统的最优控制问题,特别是在存在输入约束和系统动力学的情况下;②解决带有参数不确定性的线性和非线性系统的跟踪控制问题;③探索基于李雅普诺夫方法的深度强化学习在非线性系统控制中的应用;④设计和验证针对冗余机械臂的新型冗余解析方法。 其他说明:本书分为七章,每章内容相对独立,便于读者理解。书中不仅提供了理论分析,还通过实际应用(如欠驱动船舶、冗余机械臂)验证了所提方法的有效性。此外,作者鼓励读者通过仿真和实验进一步验证书中提出的理论和技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值