zoukankan      html  css  js  c++  java
  • poj 1386 Play on Words门上的单词【欧拉回路&&并查集】

    题目链接:http://poj.org/problem?id=1386

    题目大意:给你若干个字符串,一个单词的尾部和一个单词的头部相同那么这两个单词就可以相连,判断给出的n个单词是否能够一个接着一个全部连通。

    解题思路:其实就是让你判断是否是欧拉回路或欧拉通路,建图需要一点思维,把26个字母当成是节点,每个单词当成是一条有向边。

    这题自己先实现了一遍,发现虽然样例能过,但是有些情况没有考虑到,然后看了一下别人的代码,发现大部分人都是用并查集来做的,很巧妙的做法。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    
    char word[1001];
    int father[27], out[27], in[27], vis[30];
    
    int find_(int x)
    {
        if (father[x] != x)
            father[x] = find_(father[x]);
        return father[x];
    }
    
    void mergee(int a, int b)
    {
        if (find_(a) != find_(b))
            father[find_(a)] = find_(b);
    }
    
    void Init()
    {
        memset(out, 0, sizeof(out));
        memset(in, 0, sizeof(in));
        for (int i = 0; i < 26; i++)
            father[i] = i;
        memset(vis, 0, sizeof(vis));
    }
    
    int main()
    {
        int T;
        cin >> T;
        int n;
        while (T--)
        {
            cin >> n;
            Init();
            while (n--)
            {
                scanf("%s", word);
                int u = word[0] - 'a';
                int v = word[strlen(word) - 1] - 'a';
                mergee(u, v);
                out[u] ++;
                in[v] ++;
                vis[u] = vis[v] = 1;
            }
            int cnt = 0, cnt1 = 0, cnt2 = 0;
            for (int i = 0; i < 26; i++)
            {
                if (vis[i] && father[i] == i)
                {
                    cnt++;
                }
            }
            if (cnt > 1)
            {
                puts("The door cannot be opened.");
                continue;
            }
            bool flag = true;
            for (int i = 0; i < 26; i++)
            {
                if (vis[i] && out[i] != in[i])
                {
                    if (out[i] - in[i] == 1)
                    {
                        cnt1++;
                        if (cnt1 > 1)
                        {
                            flag = false;
                            break;
                        }
                    }
                    else if (in[i] - out[i] == 1)
                    {
                        cnt2++;
                        if (cnt2 > 1)
                        {
                            flag = false;
                            break;
                        }
                    }
                    else
                    {
                        flag = false;
                        break;
                    }
                }
            }
            if (!flag) puts("The door cannot be opened.");
            else puts("Ordering is possible.");
        }
        return 0;
    }

    2018-04-03


    作者:is_ok
    出处:http://www.cnblogs.com/00isok/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    HDU4126
    训练赛Day6-The 36th ACMICPC Asia Regional Beijing Site
    弦图
    HDU4821 字符串哈希+尺取
    HDU1854
    HDU1166
    输入输出挂
    LightOj 1027 数学期望
    HDU
    HDU
  • 原文地址:https://www.cnblogs.com/00isok/p/8710740.html
Copyright © 2011-2022 走看看