P1341 无序字母对 - 欧拉(回)路

Posted loi-brilliant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1341 无序字母对 - 欧拉(回)路相关的知识,希望对你有一定的参考价值。

传送门

将字母看做点,将相邻字母见看做有连一条无向边,最终判断能否形成一条由n+1个点构成的路径,即是否存在一条欧拉路或欧拉回路。

由于要字典序最小,所以按字典序从小到大遍历,找最小的字母为起点,每次找最小的字母作为下一个点。

由于欧拉(回)路是倒序存储的,所以输出答案时需要倒着输出。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2000,M=50000+100;
bool e[100][100];
int deg[100];
int c(char a){
    if(a>=a&&a<=z) return a-a+27;
    return a-A+1;
}
char pout(int a){
    if(a>=1&&a<=26) printf("%c",a+A-1);
    else printf("%c",a+a-27);
}
int ans[100000],t;
int root=(1<<30);
void dfs(int u){
    for(int i=1;i<=52;i++){
        if(e[u][i]||e[i][u]){
            e[u][i]=e[i][u]=0;
            dfs(i);
        }
    }
    ans[++t]=u;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        char u,v;
        cin>>u>>v;
        e[c(u)][c(v)]=e[c(v)][c(u)]=1;
        deg[c(v)]++,deg[c(u)]++;
    }
    int cnt=0;
    for(int i=1;i<=52;i++) if(deg[i]%2) {
        cnt++;root=min(root,i);
    }
    if(cnt!=2&&cnt) {
        printf("No Solution
");return 0;
    }
    if(!cnt) {
        for(int i=1;i<=52;i++)
            if(deg[i]) {
                root=i;break;
            }
    }
    dfs(root);
    for(int i=t;i>=1;i--){
        pout(ans[i]);
    }
    return 0;
}

 

以上是关于P1341 无序字母对 - 欧拉(回)路的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P1341 无序字母对 Label:欧拉路 一笔画

[P1341]无序字母对 (欧拉回路)

P1341 无序字母对(欧拉回路)

洛谷P1341 无序字母对(欧拉回路)

P1341 无序字母对(欧拉回路)

P1341 无序字母对欧拉路径- Hierholzer模板