NYOJ99单词拼接

来源:互联网 发布:fanuc机器人编程实例 编辑:程序博客网 时间:2024/06/06 18:58

NYOJ99

     思路 :  把 单词两端的字母看成点,单词本身看成一个权重一样,用来排序以谁为开头。

                             只需判断是否欧拉图

                                          根据入度出度判断 

                                          判断是否连通 (并查集)

                             若是,再深搜输出路径。



参考:  

nyoj 单词拼接(并查集判断连通性+欧拉路径)

#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;int f[26],in[26],out[26],vis[1005],path[1005],ext[1005];struct node {int u,v;char a[31];}an[1005];int cmp(struct node b ,struct node c){   return strcmp(b.a ,c.a) < 0 ;} void init(){memset(in,0,sizeof(in));memset(out,0,sizeof(out));memset(ext,0,sizeof(ext));int i;for(i = 0;i<26;i++){f[i] = i;}}int find(int a){if( f[a] == a )return a;return find(f[a]);}void merge(int u ,int v){int l = find(u);int r = find(v);f[r] = l;}int dfs(int u , int n , int cen){if(cen == n )return 1;   int f =0,i;for(i = 0;i<n;i++ ){    if(vis[i]  == 0 && an[i].u  == u ){vis[i] = 1;path[cen] = i;f = dfs(an[i].v ,n, cen+1);        vis[i] = 0;if(f == 1)return 1;}}return 0;}int main(){int M,n,l;int i,j,k,c,c1,c2,start;char a[31];scanf("%d",&M);while(M--){init();scanf("%d",&n);for(i = 0;i<n;i++){scanf("%s",&a);l = strlen(a);an[i].u = a[0] -'a';an[i].v = a[l-1] -'a';strcpy(an[i].a , a );merge(an[i].u,an[i].v);}sort(an,an+n,cmp);for(i = 0;i<n;i++){ in[an[i].v]++;out[an[i].u]++;ext[an[i].v] = ext[an[i].u] = 1;}start = 0;c= 0;c1 = c2 = 0;for(i = 0;i<26;i++){if(ext[i] && f[i] == i )//联通判断 只允许存在的点中同属于一个集合,即只有一个点等于它本身{c++;if(c>1)break;}if(in[i] == out[i])continue;else { if( in[i] == out[i] +1)c1++; else if( in[i] + 1 == out[i]) { c2++;start = i;            //标记深搜的起始位置 } else break;}        }         if((c1 == c2 || (c1<2) )&& i==26 && dfs(start,n,0))  //dfs可放入if条件里面   {printf("%s",an[path[0]].a);for(i = 1;i<n;i++){printf(".%s",an[path[i]].a);}printf("\n");continue;}printf("***\n");}}


                          


                           

0 0
原创粉丝点击