题意:给你n个单词,问你能不能形成欧拉路径
欧拉路径和欧拉回路
欧拉路径:从某结点出发一笔画成所经过的路线叫做欧拉路径。
欧拉回路:在欧拉路径的基础上又回到起点。
a、凡是由偶点组成的连通图,一定可以一笔画成。画时可以把任一偶点为起点,最后一定能以这个点为
终点画完此图。
b、凡是只有两个奇点的连通图(其余都为偶点),一定可以一笔画成。画时必须把一个奇点为起点,另
一个奇点终点。
c、其他情况的图都不能一笔画出。(有偶数个奇点除以2便可算出此图需几笔画成。)
欧拉回路和欧拉路径的判断
欧拉回路:
无向图:每个顶点的度数都是偶数,则存在欧拉回路。
有向图:每个顶点的入度都等于出度,则存在欧拉回路。
欧拉路径:
无向图:当且仅当该图所有顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。
有向图:当且仅当该图所有顶点 出度=入度 或者 一个顶点 出度=入度+1,另一个顶点 入度=出度+1,其
他顶点 出度=入度。
判断完欧拉路径后,则可以用fleury算法输出路径
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <iostream>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
string s[1005];
int out[26],in[26],cnt;
int ans[1005],head[30];
struct node
{
int nxt,to,id,vv;
}edge[2010];
void add(int u,int v,int id)
{
edge[++cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
edge[cnt].id=id;
edge[cnt].vv=0;
}
void dfs(int u)
{
for(int i=head[u];~i;i=edge[i].nxt)
if(!edge[i].vv)
{
edge[i].vv=1;
dfs(edge[i].to);//回溯来记录
ans[cnt++]=edge[i].id;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
memset(out,0,sizeof(out));
memset(in,0,sizeof(in));
memset(head,-1,sizeof(head));
for(int i=0; i<n; i++)
{
cin>>s[i];
in[s[i][0]-'a']++;
out[s[i][s[i].length()-1]-'a']++;
}
int c1=0,c2=0,st=100;
for(int i=0;i<26;i++)
{
if(in[i]-out[i]==1)
c1++,st=i;
else if(in[i]-out[i]==-1)
c2++;
else if(out[i]-in[i]!=0)
c1=3;
}
if(!((c1==0&&c2==0)||(c1==1&&c2==1)))
{
puts("***");
continue;
}
sort(s,s+n);
cnt=0;
for(int i=n-1; i>=0; i--)
{
int u=s[i][0]-'a',v=s[i][s[i].length()-1]-'a';
add(u,v,i);
if(c1) continue;
st=min(st,u);
st=min(st,v);
}
cnt=0;
dfs(st);
if(cnt!=n)
puts("***");
else
{
cout<<s[ans[cnt-1]];
for(int i=cnt-2;i>=0;i--)
cout<<"."<<s[ans[i]];
puts("");
}
}
}