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\n");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;
}

 

转载于:https://www.cnblogs.com/Loi-Brilliant/p/9124313.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值