zoukankan      html  css  js  c++  java
  • POJ 2337 Catenyms (有向图欧拉路径,求字典序最小的解)

    Catenyms
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 8756   Accepted: 2306

    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
    ***
    

    Source

     
     
     
     

    把26个小写字母当成点,每个单词就是一条边。

    然后就是求欧拉路径。

    为了保证字典序最小,要先排序,加边要按照顺序加。

    而且求解的dfs起点要选择下,选择最小的。

      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2014-2-3 13:12:43
      4 File Name     :E:2014ACM专题学习图论欧拉路有向图POJ2337.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 struct Edge
     21 {
     22     int to,next;
     23     int index;
     24     bool flag;
     25 }edge[2010];
     26 int head[30],tot;
     27 void init()
     28 {
     29     tot = 0;
     30     memset(head,-1,sizeof(head));
     31 }
     32 void addedge(int u,int v,int index)
     33 {
     34     edge[tot].to = v;
     35     edge[tot].next = head[u];
     36     edge[tot].index = index;
     37     edge[tot].flag = false;
     38     head[u] = tot++;
     39 }
     40 string str[1010];
     41 int in[30],out[30];
     42 int cnt;
     43 int ans[1010];
     44 void dfs(int u)
     45 {
     46     for(int i = head[u] ;i != -1;i = edge[i].next)
     47         if(!edge[i].flag)
     48         {
     49             edge[i].flag = true;
     50             dfs(edge[i].to);
     51             ans[cnt++] = edge[i].index;
     52         }
     53 }
     54 int main()
     55 {
     56     //freopen("in.txt","r",stdin);
     57     //freopen("out.txt","w",stdout);
     58     int T,n;
     59     scanf("%d",&T);
     60     while(T--)
     61     {
     62         scanf("%d",&n);
     63         for(int i = 0;i < n;i++)
     64             cin>>str[i];
     65         sort(str,str+n);//要输出字典序最小的解,先按照字典序排序
     66         init();
     67         memset(in,0,sizeof(in));
     68         memset(out,0,sizeof(out));
     69         int start = 100;
     70         for(int i = n-1;i >= 0;i--)//字典序大的先加入
     71         {
     72             int u = str[i][0] - 'a';
     73             int v = str[i][str[i].length() - 1] - 'a';
     74             addedge(u,v,i);
     75             out[u]++;
     76             in[v]++;
     77             if(u < start)start = u;
     78             if(v < start)start = v;
     79         }
     80         int cc1 = 0, cc2 = 0;
     81         for(int i = 0;i < 26;i++)
     82         {
     83             if(out[i] - in[i] == 1)
     84             {
     85                 cc1++;
     86                 start = i;//如果有一个出度比入度大1的点,就从这个点出发,否则从最小的点出发
     87             }
     88             else if(out[i] - in[i] == -1)
     89                 cc2++;
     90             else if(out[i] - in[i] != 0)
     91                 cc1 = 3;
     92         }
     93         if(! ( (cc1 == 0 && cc2 == 0) || (cc1 == 1 && cc2 == 1) ))
     94         {
     95             printf("***
    ");
     96             continue;
     97         }
     98         cnt = 0;
     99         dfs(start);
    100         if(cnt != n)//判断是否连通
    101         {
    102             printf("***
    ");
    103             continue;
    104         }
    105         for(int i = cnt-1; i >= 0;i--)
    106         {
    107             cout<<str[ans[i]];
    108             if(i > 0)printf(".");
    109             else printf("
    ");
    110         }
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3537544.html
Copyright © 2011-2022 走看看