POJ 2337 欧拉回路

题意:
如果给出的单词能够首尾相接,请按字典序输出单词,中间要加’.’
否则输出三个”*”.
思路:
欧拉回路
记得按字典序排序哦~
加边的时候要倒着加。(邻接表遍历的时候是反着的)

记得清空vis数组(因为这个无脑错误WA了好长时间。。。。。)

随便搞搞 就能过了。 数据不是很强…

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[1005][25];
int first[60],next[1005],tot,top,v[1005];
int cases,n,ansx,ansy,ansz,in[26],out[26],ans[1005];
bool vis[1005],flag,VIS[26];
struct node{char str[25];int length;}edge[1005];
void add(int x,int y,int z){v[z]=y;next[z]=first[x];first[x]=z;}
bool cmp(node x,node y){return strcmp(x.str,y.str)>0?0:1;}
void dfs(int x){
    for(int i=first[x];~i;i=next[i])
        if(!vis[i]){
            VIS[v[i]]=1;
            vis[i]=1,dfs(v[i]);
            ans[++top]=i;
        }
}
int main(){
    scanf("%d",&cases);
    while(cases--){
        memset(first,-1,sizeof(first));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(vis,0,sizeof(vis));
        memset(VIS,0,sizeof(VIS));
        flag=ansx=ansy=ansz=top=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",edge[i].str);
            edge[i].length=strlen(edge[i].str);
            out[edge[i].str[0]-'a']++;
            in[edge[i].str[edge[i].length-1]-'a']++;
        }
        sort(edge+1,edge+1+n,cmp);
        for(int i=n;i;i--)
            add(edge[i].str[0]-'a',edge[i].str[edge[i].length-1]-'a',i);
        for(int i=0;i<=25;i++){
            if(in[i]-out[i]==1)ansx++;
            else if(out[i]-in[i]==1)ansy++;
            else if(in[i]!=out[i])ansz++;
        }
        if(!ansz&&ansx==ansy&&(ansx==0||ansx==1)){
            int jy;
            if(ansx==1){
                for(int i=0;i<26;i++)
                    if(out[i]-in[i]==1){jy=i;break;}
            }
            else{
                for(int i=0;i<26;i++)
                    if(out[i]){jy=i;break;}
            }
            VIS[jy]=1;
            dfs(jy);
            for(int i=0;i<=25;i++)
                if((in[i]||out[i])&&!VIS[i])flag=1;
        }
        else flag=1;
        if(!flag){
            for(int i=top;i>=2;i--)
            printf("%s.",edge[ans[i]].str);
            printf("%s\n",edge[ans[1]].str);
        }
        else puts("***");
    }
}

这里写图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值