欧拉回路打印路径poj2337

来源:互联网 发布:数据详情分析的工具 编辑:程序博客网 时间:2024/05/07 23:16

思路:先对单词排序,然后同一个单词的首尾字母之间加一条边,然后判断欧拉回路是否存在,然后dfs打印路径

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<string>#include<algorithm>using namespace std;const int maxn=1010;int n,in[30],out[30],pre[30];vector<pair<int,int> > grid[30];string a[maxn];vector<string> ans;bool vis[maxn*10],visa[30];int Find(int x){    if(x==pre[x])return x;    return pre[x]=Find(pre[x]);}bool cmp(pair<int,int> c,pair<int,int> b){    return a[c.first]<a[b.first];}void add_edge(){    memset(in,0,sizeof(in));    memset(out,0,sizeof(out));    memset(visa,0,sizeof(visa));    for(int i=0;i<26;i++)grid[i].clear();    for(int i=0;i<n;i++)    {        int len=a[i].size();        int x=a[i][0]-'a',y=a[i][len-1]-'a';        out[x]++,in[y]++;        visa[x]=visa[y]=1;        if(Find(x)!=Find(y))        pre[y]=x;        grid[x].push_back(make_pair(i,y));    }}void dfs(int u){    int len=grid[u].size();    for(int i=0;i<len;i++)    {        int v=grid[u][i].first;        if(vis[v])continue;        vis[v]=1;        dfs(grid[u][i].second);        ans.push_back(a[v]);    }}bool solve(){    int cnt=0,cnt1=0,cnt2=0;    for(int i=0;i<26;i++)    {        if(visa[i]&&Find(i)==i)cnt++;    }    if(cnt>1){return false;}    int st=0;    for(int i=0;i<26;i++)    {        if(!visa[i])continue;        if(in[i]!=out[i])        {            if(in[i]-out[i]==1)cnt1++;            else if(out[i]-in[i]==1){cnt2++;st=i;}            else return false;        }    }    if(cnt1>1||cnt2>1||cnt1!=cnt2)return false;    if(cnt1==cnt2&&cnt1==0)    {        for(int i=0;i<26;i++)            if(visa[i])            {st=i;break;}    }    memset(vis,0,sizeof(vis));    ans.clear();    dfs(st);    int len=ans.size();    if(len<=0)return false;    cout<<ans[len-1];    for(int i=len-2;i>=0;i--)cout<<"."<<ans[i];    cout<<endl;    return true;}int main(){    //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i=0;i<26;i++)pre[i]=i;        for(int i=0;i<n;i++)cin>>a[i];        sort(a,a+n);        add_edge();        if(!solve())printf("***\n");    }    return 0;}


0 0