POJ-2337-Catenyms(欧拉路)

题意是求一个欧拉路,并以字典序输出

要欧拉路以字典序输出,则一开始将边进行排序,然后构图,选择字典序最小的可用点作为开始点查找欧拉路,然后倒序输出,即可。(不知道证明。。。。。)

 

// File Name: 2337.cpp
// Author: zlbing
// Created Time: 2013/3/10 15:36:00

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,n) for(int i=0;i<n;i++)
#define REP1(i,n) for(int i=1;i<n+1;i++)
#define MAXN 1000+50
struct Str{
    char str[30];
}S[MAXN];
bool cmp(const Str& a,const Str& b){
    int t=strcmp(a.str,b.str);
    if(t<=0)return true;
    else return false;
}
struct Edge{
    int from,to;
};
vector<Edge> edges;
vector<int>G[MAXN];
int vis[MAXN];
vector<int>ans;
void dfs(int u){
    for(int i=0;i<G[u].size();i++){
        int m=G[u][i];
        if(vis[m])continue;
        vis[m]=1;
        dfs(edges[m].to);
        ans.push_back(m);
    }
}
int main(){
    int cas;
    scanf("%d",&cas);
    while(cas--){
        int n;
        scanf("%d",&n);
        REP(i,n){
            scanf("%s",S[i].str);
        }
        sort(S,S+n,cmp);
        edges.clear();
        REP(i,30)G[i].clear();
        REP(i,n){
            int len=strlen(S[i].str);
            edges.push_back((Edge){(int)(S[i].str[0]-'a'),(int)(S[i].str[len-1]-'a')});
            int m=edges.size();
            G[S[i].str[0]-'a'].push_back(m-1);
        }
        int degr[30],degc[30];
        CL(degr,0);
        CL(degc,0);
        REP(i,26){
            REP(j,G[i].size()){
                degc[i]++;
                degr[edges[G[i][j]].to]++;
            }
        }
        int st=-1,et=-1;
        bool flag=false;
        int cnt=0;
        REP(i,26){
            if(degc[i]!=degr[i]){
                if(abs(degr[i]-degc[i])>1)flag=true;
                if(degr[i]-degc[i]!=0){
                    cnt++;
                    if(degr[i]-degc[i]==1&&et==-1)
                        et=i;
                    else if(degc[i]-degr[i]==1&&st==-1)
                        st=i;
                    else flag=true;
                }
            }
        }
        if(flag||(cnt!=2&&cnt!=0)){
            puts("***");
            continue;
        }
        if(st==-1){
            REP(i,26){
                if(G[i].size()!=0){
                    st=i;break;
                }
            }
        }
        CL(vis,0);
        ans.clear();
        dfs(st);
        if(ans.size()!=n){
            puts("***");
            continue;
        }
        printf("%s",S[ans[n-1]].str);
        for(int i=n-2;i>=0;i--)printf(".%s",S[ans[i]].str);
        printf("\n");
    }
    return 0;
}

 

posted @ 2013-03-10 16:38  z.arbitrary  阅读(247)  评论(0编辑  收藏  举报