唉,zoj过了,poj挂了,不知道错在哪了,无解!
题意:很多单词,如果单词1的最后一个字每和单词2的第一个字母相同,那么这两个单词就可以连在一起,问所有的单词能不能连在一起,并按字典序输出。
{
有向图存在欧拉通路或回路的条件最多只有来两个节点的入度不等于初度,并且一个的in+1==out,另一个out+1==in;
}
把首位字母看成点,单词看成边,就是找欧拉回路或欧拉通路。如果是欧拉回路,那么找字典序最小的那个做起点,如果是欧拉通路,就是入度+1=初度的为起点。
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
vector<int>e[1001];
int p[30],in[30],out[30],n,t,r,c;
int q[1111],vis[1111];
char s[1111][30];
int cmp(const void *s1,const void *s2)//qsort给字符串排序中的cmp;
{
return strcmp((char *)s1,(char *)s2)>0;
}
void init()
{
memset(vis,0,sizeof(vis));
int i;
for(i=1;i<=26;i++)
{
in[i]=out[i]=0;
p[i]=i;
}
for(i=0;i<=1000;i++)
e[i].clear();
}
int find(int i)
{
if(p[i]!=i) return find(p[i]);
return p[i];
}
void mege(int a,int b)
{
a=find(a);
b=find(b);
if(a!=b)
p[b]=a;
}
void Print(int i)//打印结果
{
if(i!=-1)
{
Print(q[i]);
if(c<n-1)
printf("%s.",s[i]);
else
printf("%s",s[i]);
c++;
}
else
return;
}
void dfs(int i,int w)//dfs,当w==n时dfs结束。
{
if(w==n)
{
r=1;
Print(i);
return;
}
else
{
if(r==0)
{
int j,l;
for(j=0;j<e[i].size();j++)//vector存的是能与i相连的单词
{
l=e[i][j];
if(!vis[l]&&i!=l)
{
vis[l]=1;
q[l]=i;
dfs(l,w+1);
vis[l]=0;
}
}
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
int i,j,start=0;
r=c=0;
init();
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",s[i]);
int L=strlen(s[i]);
int a=s[i][0]-'a'+1;
int b=s[i][L-1]-'a'+1;
in[b]++;
out[a]++;
vis[a]=vis[b]=1;
mege(a,b);
}
int tag=0,x=0,y=0,other=0,flag;//如果联通,那么tag应该==1;
for(i=1;i<=26;i++)
{
if(vis[i])
{
if(find(i)==i)
tag++;
if(out[i]!=in[i])
{
if(in[i]+1==out[i])
x++;
else if(in[i]-1==out[i])
y++;
else
other++;
}
}
}
if(tag==1&&other==0&&((x==0&&y==0)||(x==1&&y==1)))
flag=1;
else
flag=0;
if(!flag)
{
printf("***\n");
}
else
{
qsort(s,n,sizeof(s[0]),cmp);
if(x==0&&y==0)//找起点
{
for(i=1;i<=26;i++)
if(vis[i])
{
start=i;break;
}
}
else
{
for(i=1;i<=26;i++)
{
if(vis[i]&&in[i]+1==out[i])
{
start=i;break;
}
}
}
for(i=0;i<n;i++)
{
int l=strlen(s[i]);
for(j=0;j<n;j++)//找出i能与哪些相连
{
if(i!=j&&s[i][l-1]==s[j][0])
e[i].push_back(j);
}
}
for(i=0;i<n;i++)
{
if(s[i][0]-'a'+1==start)
{
memset(vis,0,sizeof(vis));
q[i]=-1;
vis[i]=1;
dfs(i,1);
}
if(r) break;
}
printf("\n");
}
}
return 0;
}