poj-2337(欧拉回路输出)

题意:给你n个字符串,每个字符串可以和另一个字符串连接的前提是,前一个字符串的尾字符等于后一个字符串的首字符,问你存不存在欧拉通路并输出

解题思路:基本标准流程,建图:把一个字符串可以看作一条首字符指向尾字符的一条边,因为这道题需要输出字典序最小的,那么得先给他排序,按照字典序从小到大排,因为我用前向星存图,所以首字符相同的,按尾字符从大到小排

建完图后查看是否存在欧拉路径,如果存在,就输出,输出用dfs回溯的方法输出的;

代码:

#include<iostream>
#include<algorithm>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
const int maxn=5005;
struct Edge
{
    int next;
    int to;
    int num;
    int flag;
}edge[maxn];
int head[maxn];
int cnt,n,m,x,y,start;
int visit[30],f[30],ing[30],oug[30];
string s[1050];
stack<int>q;
int findfa(int u)
{
    if(u==f[u])
        return u;
    else
    {
        f[u]=findfa(f[u]);
        return f[u];
    }
}
void join(int u,int v)
{
    int t1=findfa(u);
    int t2=findfa(v);
    if(t2!=t1)
        f[t2]=t1;
}
bool cmp(const string a, const string b)
{
	if(a[0]==b[0])return a>b;
	return a<b;
}
void add(int u,int v,int i)
{
    edge[cnt].next=head[u];edge[cnt].to=v;
    edge[cnt].flag=0;edge[cnt].num=i;head[u]=cnt++;
}
void dfs(int u)
{
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(edge[i].flag==0)
        {
            edge[i].flag=1;
            dfs(v);
            q.push(edge[i].num);
        }
    }
}
int check()
{
    int num=0;
    for(int i=1;i<=26;i++)
    {
        if(visit[i]==1&&findfa(i)==i)
            num++;
        if(num>=2)
            return -1;
    }
    int cnt1=0,cnt2=0;
    for(int i=1;i<=26;i++)
    {
        if(visit[i]==0)
            continue;
        if(ing[i]==oug[i])
            continue;
        if(ing[i]==oug[i]+1)
        {
            cnt1++;continue;
        }
        if(ing[i]==oug[i]-1)
        {
            start=i;cnt2++;continue;
        }
        return -1;
    }
    if(cnt1==cnt2&&cnt1==0)
        return 1;
    if(cnt1==cnt2&&cnt1==1)
        return 2;
    return -1;
}
void init()
{
    memset(visit,0,sizeof(visit));
    memset(ing,0,sizeof(ing));
    memset(oug,0,sizeof(oug));
    memset(head,-1,sizeof(head));
    cnt=0;
    for(int i=1;i<=30;i++)
        f[i]=i;
}
int main()
{
    int tt;
    cin>>tt;
    while(tt--)
    {
        init();
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>s[i];
        sort(s+1,s+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            m=s[i].size();
            x=s[i][0]-'a'+1;y=s[i][m-1]-'a'+1;
            add(x,y,i);join(x,y);oug[x]++;ing[y]++;visit[x]=1;visit[y]=1;
        }
        int xx=check();
        if(xx==-1)
            cout<<"***\n";
        else if(xx==1)
        {
            dfs(s[1][0]-'a'+1);
            int mm=q.size();int cot=0;
            while(!q.empty())
            {
                cot++;
                cout<<s[q.top()];q.pop();
                if(cot<mm)
                    cout<<".";
            }
            cout<<endl;
        }
        else if(xx==2)
        {
            dfs(start);
            int mm=q.size();int cot=0;
            while(!q.empty())
            {
                cot++;
                cout<<s[q.top()];q.pop();
                if(cot<mm)
                    cout<<".";
            }
            cout<<endl;
        }
    }
}

  

posted @ 2018-09-14 00:53  荒岛的龟  阅读(310)  评论(0编辑  收藏  举报