zoukankan      html  css  js  c++  java
  • 有向图欧拉通路

    2337

    Catenyms
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 9454   Accepted: 2486

    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
    ***
    分析:

    题目的意思是给出来n个单词,看看是否能连成一条单词串,要把每个单词都搜索一遍很容易想到是欧拉通路,以每个单词的首字母和末字母为定点建边,权值状态为该单词,编号a,b,c……为1,2,3,……

    首先用并查集判断改图是否是连通图不是的话输出***

    然后判断该图是欧拉通路还是欧拉回路,若是欧拉回路的话从最小的点开始深搜,若是欧拉通路的话从出度比入度大一的点开始深搜,否则输出***

    此题还让输出结果保证字典序最小,让单词按照逆序快排即可

    定义:

    1.无向图存在欧拉回路的充要条件:

       连通且没有奇度顶点。

    2.无向图存在欧拉路径的充要条件:

       连通且奇度顶点个数为2

    3.有向图存在欧拉路径的充要条件:

       基图连通且存在某顶点入度比出度大1,另一顶点出度比入度大1,其余顶点入度等于出

    4.有向图存在欧拉回路的充要条件:

       基图连通且所有顶点入度等于出度。

    程序:

    #include"stdio.h"
    #include"string.h"
    #include"queue"
    #include"stack"
    #include"iostream"
    #include"string"
    #include"map"
    #include"stdlib.h"
    #define inf 99999999
    #define M 10009
    using namespace std;
    struct st
    {
        int u,v,w,next,vis;
    }edge[M];
    int head[M],use[M],s[M],out[M],in[M];
    int t,num;
    int f[M];
    int finde(int x)
    {
        if(x!=f[x])
            f[x]=finde(f[x]);
        return f[x];
    }
    void make(int a,int b)
    {
        f[finde(a)]=finde(b);
    }
    int cmp(const void *a,const void *b)
    {
        return strcmp((char *)b,(char *)a);
    }
    void init()
    {
        t=0;
        memset(head,-1,sizeof(head));
        memset(out,0,sizeof(out));
        memset(in,0,sizeof(in));
        memset(use,0,sizeof(use));
        memset(edge,0,sizeof(edge));
        for(int i=0;i<=100;i++)
            f[i]=i;
    }
    void add(int u,int v,int w)
    {
        edge[t].u=u;
        edge[t].v=v;
        edge[t].w=w;
        edge[t].next=head[u];
        head[u]=t++;
    }
    void DFS(int u)
    {
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(!edge[i].vis)
            {
                edge[i].vis=1;
                DFS(v);
                s[num++]=edge[i].w;
            }
        }
    }
    char ch[M][111];
    int main()
    {
        int T,i,a,b,n,m;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(i=0;i<n;i++)
                scanf("%s",ch[i]);
            qsort(ch,n,sizeof(ch[0]),cmp);
            init();
            for(i=0;i<n;i++)
            {
                m=strlen(ch[i]);
                a=ch[i][0]-'a'+1;
                b=ch[i][m-1]-'a'+1;
                use[a]=1;
                use[b]=1;
                make(a,b);
                add(a,b,i);
                out[a]++;
                in[b]++;
            }
            int tmp=finde(a);
            int flag=0;
            for(i=1;i<=26;i++)
            {
                if(use[i]&&finde(i)!=tmp)
                    flag++;
            }
            if(flag)
            {
                printf("***
    ");continue;
            }
            int f1=0,f2=0,ff=0;
            for(i=1;i<=26;i++)
            {
                if(!use[i])
                    continue;
                if(out[i]-in[i]>1||in[i]-out[i]>1)
                    ff++;
                if(out[i]==in[i]+1)
                    f1++;
                if(out[i]+1==in[i])
                    f2++;
            }
            if(f1==0&&f2==0&&ff==0)
            {
                num=0;
                for(i=1;i<=26;i++)
                {
                    if(use[i])
                    {
                        DFS(i);
                        break;
                    }
                }
                for(i=num-1;i>=0;i--)
                {
                    if(i==num-1)
                        printf("%s",ch[s[i]]);
                    else
                        printf(".%s",ch[s[i]]);
                }
                printf("
    ");
            }
            else if(f1==1&&f2==1&&ff==0)
            {
                num=0;
                for(i=1;i<=26;i++)
                {
                    if(use[i]&&in[i]+1==out[i])
                    {
                        DFS(i);
                        break;
                    }
                }
                for(i=num-1;i>=0;i--)
                {
                    if(i==num-1)
                        printf("%s",ch[s[i]]);
                    else
                        printf(".%s",ch[s[i]]);
                }
                printf("
    ");
            }
            else
                printf("***
    ");
        }
    }
    


  • 相关阅读:
    细心也是一种态度
    EDM数据访问的三种方式
    如何快速提交网站备案 ICP备案
    c# winform 关于给静态全局变量赋值的问题
    c#DIY随机数类winform 2010
    手把手教你如何用IIS搭建手机WAP网站(图文)
    admin密码对应的MD5值,16位和32位,admin解密自己留着方便.
    C#实现MD5加密,winform c#2005
    最全的c#日期函数 winform
    如何解决因网站备案号没下来而网站被迫关闭的办法
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348210.html
Copyright © 2011-2022 走看看