码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-06-02 11:16:08      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:字典序   const   答案   pre   scan   string   存储   ref   break   

传送门

将字母看做点,将相邻字母见看做有连一条无向边,最终判断能否形成一条由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;
}

 

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

标签:字典序   const   答案   pre   scan   string   存储   ref   break   

原文地址:https://www.cnblogs.com/Loi-Brilliant/p/9124313.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!