[luogu1341] 无序字母对

欧拉路径模板,但是细节有点多……

存在欧拉路径的条件:

  • 图连通 : 使用并查集维护
  • 只有两个点的度为奇数,或者没有一个点
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1005

bool vis[MAXN];
int fa[MAXN];
int dre[MAXN];
bool G[MAXN][MAXN];
int st[MAXN],top = 0;
int N;

inline int f1(char ch) {
    return ch > 'Z' ? ch - 'a' + 27 : ch - 'A' + 1;
}

inline char f2(int num) {
    return num > 26 ? num - 27 + 'a' : num - 1 + 'A';
}

int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

inline void merge(int u,int v) {
    if(find(u)==find(v)) return;
    fa[find(u)] = find(v);
}

inline int get_ch() {
    char ch = getchar();
    while(ch<'A'||(ch>'Z'&&ch<'a')||ch>'z') ch = getchar();
    return f1(ch);
}

void dfs(int u) {
    
    for(int i=1;i<MAXN;++i) {
        if(!vis[i]) continue;
        if(!G[u][i]) continue;
        G[u][i] = G[i][u] = false;
        dfs(i);
    }
    st[++top] = u;
}

int main() {

    int u,v;
    std::memset(G,0,sizeof(G));
    std::memset(dre,0,sizeof(dre));
    std::memset(vis,false,sizeof(vis));

    for(int i=1;i<MAXN;++i) fa[i] = i;

    scanf("%d",&N);
    for(int i=1;i<=N;++i) {
        u = get_ch(); v = get_ch();
        G[u][v] = G[v][u] = true;
        dre[u] ++; dre[v] ++;
        vis[u] = vis[v] = true;
        merge(u,v);
    }

    bool flag = true;
    int last = -1;
    int count = 0;
    int first = -1;

    for(int i=1;i<MAXN;++i) {
        
        if(!vis[i]) continue;
        if(last==-1) last = find(i);
        else if(find(i)!=last) {
            flag = false;
            break;
        }

        if((dre[i]&1)==1) {
            if(first==-1) first = i;
            count ++;
        } 
        
    }

    if(count!=0&&count!=2) flag = false;
    if(count==0) {
        for(int i=1;i<MAXN;++i) {
            if(vis[i]) {
                first = i;
                break;
            }
        }
    }
    
    if(!flag) {
        puts("No Solution");
        return 0;
    }

    dfs(first);
    for(int i=top;i>0;--i) printf("%c",f2(st[i]));
    return 0;
}

转载于:https://www.cnblogs.com/Neworld2002/p/10332295.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值