无序字母对(无向图求欧拉路径)

题目描述

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

输入格式

第一行输入一个正整数n。

以下n行每行两个字母,表示这两个字母需要相邻。

输出格式

输出满足要求的字符串。

如果没有满足要求的字符串,请输出“No Solution”。

如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

大意就是给你n条无向路,让你找一个字典序最小的欧拉路径

#include<bits/stdc++.h>
#define re return
#define R register 
#define ll long long 
#define inc(i,l,r) for(register int i=l;i<=r;++i)
using namespace std;
const int maxn=300005;
char buf[1<<21],*p1,*p2;
inline int gc(){re p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} 
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

int m,vis[70][70],d[70];
stack<int>s;
inline void dfs(int x)
{
    inc(i,1,70)
    if(vis[x][i])
    {
        --vis[x][i];
        --vis[i][x];
        dfs(i);
    }
    s.push(x);
}
int main()
{
    char ss[10];
    int x,y;
    rd(m);
    int st=100;
    inc(i,1,m)
    {
        scanf("%s",ss);
        x=ss[0]-64;y=ss[1]-64;
        st=min(x,st);
        st=min(st,y);
        ++vis[x][y];
        ++vis[y][x];
        //可能存在不同的边连接同一条路 
        ++d[x];
        ++d[y];
    }
    
    inc(i,1,70)
    if(d[i]%2)
    {
        st=i;
        break;
    }
    int cnt=0;
    inc(i,1,70)
    if(d[i]%2)++cnt;
    if(cnt&&cnt!=2)
    {
        printf("No Solution");
        re 0;
    }
    
    dfs(st);
    while(!s.empty())
    {
        printf("%c",s.top()+64);
        s.pop();
    }
    re 0;
} 

 

不要问我为什么没用并查集判连通,数据太弱,我也很忧伤

posted @ 2019-08-15 17:21  凉如水  阅读(206)  评论(0编辑  收藏  举报