POJ 2337 欧拉回路
2016-07-17 17:17
274 查看
题意:
如果给出的单词能够首尾相接,请按字典序输出单词,中间要加’.’
否则输出三个”*”.
思路:
欧拉回路
记得按字典序排序哦~
加边的时候要倒着加。(邻接表遍历的时候是反着的)
记得清空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("***"); } }