• poj 2337(单向欧拉路的判断以及输出)


    Catenyms
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11648   Accepted: 3036

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


    题意:给定一系列字符串,如果某个字符串的结尾和另外一个字符串的开头相等,那么两个字符串就可以拼接在一起,现在问所有的字符串能否刚好都出现一次?如果存在,输出字典序最小的那个组合.

    题解:将字符串看成一条边,然后将其起始字符和结尾字符看成边的两个端点,构造一个有向图,然后就判断这个图是否为欧拉图了.判断单向欧拉图的方法:

      有向欧拉通路:起点:出度-入度=1,终点:入度-出度=1,其它点:入度==出度

      有向欧拉回路:所有点:入度==出度

      还要利用并查集判断一下这个图是否只有一个连通分量.

      然后将所有的边按照字典序排序,找到起点,进行DFS(Edge &e = edge[u][i] 这里检查了半天,一点要记得是地址啊...),即可得到答案.

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <vector>
    #include <stack>
    using namespace std;
    const int N = 2222;
    char str[100];
    struct Edge{
        char str[100];
        int to,del;
    };
    
    typedef vector <Edge> vec;
    stack <string> ans;
    vec edge[N];
    int in[N],out[N],father[N];
    bool vis[N],mark[30];
    int n;
    void init(){
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=30;i++){
            mark[i] = false;
            edge[i].clear();
            father[i] = i;
        }
    }
    int _find(int x){
        return x==father[x]?x:father[x] = _find(father[x]);
    }
    
    void dfs(int u){
        for(int i=0;i<edge[u].size();i++){
            Edge &e = edge[u][i];  ///这里要取地址
            int v = e.to;
            if(!e.del){
                e.del = 1;
                dfs(v);
                ans.push(e.str);
            }
        }
    }
    bool cmp(Edge a,Edge b){
        return strcmp(a.str,b.str)<0;
    }
    int main()
    {
        int tcase;
        scanf("%d",&tcase);
        while(tcase--){
            init();
            scanf("%d",&n);
            int S = N;
            for(int i=1;i<=n;i++){
                scanf("%s",str);
                int s = str[0]-'a'+1;
                int t = str[strlen(str)-1]-'a'+1;
                Edge e;
                e.del = 0;
                strcpy(e.str,str);
                e.to = t;
                edge[s].push_back(e);
                in[t]++;
                out[s]++;
                mark[t] = mark[s] = 1;
                int u = _find(s);
                int v = _find(t);
                if(u!=v) father[u] = v;
                S = min(S,min(s,t));
            }
            int num1 = 0,num2 = 0,num3 = 0,num4 = 0;
            for(int i=1;i<=26;i++){
                if(mark[i]==1&&father[i]==i) num4++;
                if(out[i]-in[i]==1){
                    S = i;
                    num1++;
                }
                else if(in[i]-out[i]==1){
                    num2++;
                }else if(in[i]-out[i]!=0){
                    num3++;
                }
                if(!edge[i].empty())
                sort(edge[i].begin(),edge[i].end(),cmp);
            }
            if(num3||!(num1==1&&num2==1)&&!(num1==0&&num2==0)||num4>1){
                printf("***
    ");
                continue;
            }
           dfs(S);
           int flag = 0;
           while(!ans.empty()){
                if(flag) printf(".");
                cout<<ans.top();
                flag = 1;
                ans.pop();
            }
            printf("
    ");
        }
    }
  • 相关阅读:
    求超大文件上传方案( vue )
    求超大文件上传方案( csharp )
    求超大文件上传方案( c# )
    求超大文件上传方案( .net )
    求超大文件上传方案( asp.net )
    求超大文件上传方案( php )
    求超大文件上传方案( jsp )
    用浏览器 实现断点续传 (HTTP)
    shuffle() 函数
    no.random.randn
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5962121.html
Copyright © 2020-2023  润新知