• poj 2337 Catenyms(欧拉路径+并查集)


    Catenyms
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 8078   Accepted: 2127

    Description

    A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms: 
    dog.gopher
    gopher.rat
    rat.tiger
    aloha.aloha
    arachnid.dog

    A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example, 

    aloha.aloha.arachnid.dog.gopher.rat.tiger 

    Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.

    Input

    The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.

    Output

    For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.

    Sample Input

    2
    6
    aloha
    arachnid
    dog
    gopher
    rat
    tiger
    3
    oak
    maple
    elm
    

    Sample Output

    aloha.arachnid.dog.gopher.rat.tiger
    ***
    

    思路:

    欧拉回路:图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次,

    称这条回路为欧拉回路。具有欧拉回路的图成为欧拉图。

    判断欧拉路是否存在的方法

    有向图:图连通,有一个顶点出度大入度1,有一个顶点入度大出度1,其余都是出度=入度。

    无向图:图连通,只有两个顶点是奇数度,其余都是偶数度的。

    判断欧拉回路是否存在的方法

    有向图:图连通,所有的顶点出度=入度。

    无向图:图连通,所有顶点都是偶数度。

    程序实现一般是如下过程:

    1.利用并查集判断图是否连通,即判断p[i] < 0的个数,如果大于1,说明不连通。

    2.根据出度入度个数,判断是否满足要求。

    3.利用dfs输出路径。

    代码:

     

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<stdio.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<queue>
      7 #include<stack>
      8 using namespace std;
      9 
     10 
     11 struct Nod
     12 {
     13     int next;
     14     int to;
     15     char str[30];
     16 }node[1010];
     17 
     18 int parent[30];
     19 //下面数组分别为出度,入度,存在标记,
     20 int in[30],out[30],existmark[30],used[1010],adj[30];
     21 
     22 stack<int> st;  //保存最后的结果,倒序输出
     23 
     24 //并查集1
     25 int findp(int u)
     26 {
     27     while(u!=parent[u])
     28     {
     29         u=parent[u];
     30     }
     31     return u;
     32 }
     33 
     34 //并查集2
     35 void unit(int u,int v)
     36 {
     37     int r1=findp(u);
     38     int r2=findp(v);
     39     if(r1==r2)
     40         return ;
     41     parent[r1]=r2;
     42 }
     43 
     44 //排序,字典序倒序
     45 bool cmp(Nod p1, Nod p2)
     46 {
     47     return strcmp(p1.str, p2.str) > 0;
     48 }
     49 
     50 //初始化
     51 void init()
     52 {
     53     int i;
     54     for(i=0;i<26;i++)
     55         parent[i]=i;
     56     memset(in,0,sizeof(in));
     57     memset(out,0,sizeof(out));
     58     memset(existmark,0,sizeof(existmark));
     59     memset(used,0,sizeof(used));
     60     memset(adj,-1,sizeof(adj));
     61 }
     62 //欧拉路
     63 void Eular(int start,int pos)
     64 {
     65     int i;
     66     for(i=adj[start];i!=-1;i=node[i].next)
     67     {
     68         if(!used[i])
     69         {
     70             used[i]=1;
     71             Eular(node[i].to,i);
     72         }
     73     }
     74     if(0 <= pos)
     75         st.push(pos);
     76 }
     77 
     78 int main()
     79 {
     80     int t;
     81     scanf("%d",&t);
     82     while(t--)
     83     {
     84         int n;
     85         scanf("%d",&n);
     86         init();
     87         int i,v,u;
     88         for(i=0;i<n;i++)
     89         {
     90             scanf("%s",node[i].str);
     91         }
     92         sort(node, node + n, cmp);
     93         for(i=0;i<n;i++)
     94         {
     95             u=node[i].str[0]-'a';
     96             v=node[i].str[strlen(node[i].str)-1]-'a';
     97             out[u]++;
     98             in[v]++;
     99             existmark[u]=1;
    100             existmark[v]=1;
    101             unit(u,v);
    102             node[i].to=v;
    103             node[i].next=adj[u];
    104             adj[u]=i;
    105            // cout<<i<<" "<<u<<" "<<node[i].next<<endl;
    106         }
    107 
    108         int flag=0;
    109         for(i=0;i<26;i++)
    110         {
    111             if(existmark[i]&&parent[i]==i)
    112                 flag++;
    113         }
    114         if(flag>1)
    115         {
    116             printf("***\n");
    117             continue;
    118         }
    119 
    120         int a=0,b=0,start=-1;
    121         for(i=0;i<26;i++)
    122         {
    123             if(in[i]!=out[i]&&existmark[i])
    124             {
    125                 if(1==in[i]-out[i])
    126                 {
    127                     a++;
    128                 }else if(1==out[i]-in[i])
    129                 {
    130                     b++;
    131                     start=i;
    132                 }else
    133                 {
    134                     break;
    135                 }
    136             }
    137         }
    138         if(i<26)
    139         {
    140             printf("***\n");
    141             continue;
    142         }else
    143         {
    144             if(!((0 == a + b) || (1 == a && 1 == b)))
    145             {
    146                 printf("***\n");
    147                 continue;
    148             }
    149             //a+b==0或者1==a并且1==b时
    150             if(-1==start)
    151             {
    152                 for(i=0;i<26;i++)
    153                 {
    154                     if(out[i])
    155                         break;
    156                 }
    157                 start=i;
    158             }
    159             Eular(start, -1);
    160             //输出
    161             printf("%s", node[st.top()].str);
    162             st.pop();
    163             while(!st.empty())
    164             {
    165                  printf(".%s", node[st.top()].str);
    166                  st.pop();
    167             }
    168             printf("\n");
    169         }
    170     }
    171     return 0;
    172 }

     

     

  • 相关阅读:
    第十五节课:习题讲解
    第十四节课:字典
    Python第十三节课-文件的读取和写入
    Python第十二节课--循环语句与注释
    Python第十一节课--字符串的格式化
    Python第十节课==对象的方法
    Python第九节课--初识函数
    初识函数--文件的读取和打开,已一节课一节课分开,可不看
    刷题647. Palindromic Substrings
    刷题617. Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3131334.html
Copyright © 2020-2023  润新知