zoukankan      html  css  js  c++  java
  • [POJ 1386] Play on Words

    [题目链接]

             http://poj.org/problem?id=1386

    [算法]

            将每个单词的首字母向尾字母连一条有向边,判断欧拉路径是否存在,即可

    [代码]

             

    #include <algorithm>  
    #include <bitset>  
    #include <cctype>  
    #include <cerrno>  
    #include <clocale>  
    #include <cmath>  
    #include <complex>  
    #include <cstdio>  
    #include <cstdlib>  
    #include <cstring>  
    #include <ctime>  
    #include <deque>  
    #include <exception>  
    #include <fstream>  
    #include <functional>  
    #include <limits>  
    #include <list>  
    #include <map>  
    #include <iomanip>  
    #include <ios>  
    #include <iosfwd>  
    #include <iostream>  
    #include <istream>  
    #include <ostream>  
    #include <queue>  
    #include <set>  
    #include <sstream>  
    #include <stdexcept>  
    #include <streambuf>  
    #include <string>  
    #include <utility>  
    #include <vector>  
    #include <cwchar>  
    #include <cwctype>  
    #include <stack>  
    #include <limits.h>
    using namespace std;
    #define MAXN 100010
    #define MAXLEN 1010
    #define MAXC 30
    const int M = 100000;
    
    struct edge
    {
            int to,nxt;
    } e[MAXN];
    
    int tot;
    int fa[MAXC],head[MAXC],size[MAXC],in[MAXC],out[MAXC];
    char str[MAXLEN];
    set< int > s;
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int u,int v)
    {
            tot++;
            e[tot] = (edge){v,head[u]};
            head[u] = tot;
    }
    inline int get_root(int x)
    {
            if (fa[x] == x) return x;
            return fa[x] = get_root(fa[x]);
    }
    inline void merge(int u,int v) 
    {
            int x = get_root(u) , y = get_root(v);
            if (x == y) return;
            if (size[x] < size[y]) swap(x,y); // Union By Rank
            size[x] += size[y];
            fa[y] = x;        
    } 
    
    int main() 
    {
            
            int T;
            read(T);
            while (T--)
            {
                    int n;
                    read(n);
                    for (int i = 1; i <= 26; i++) 
                    {
                            head[i] = 0;
                            fa[i] = i;
                            size[i] = 1;
                            in[i] = out[i] = 0;
                    }
                    s.clear();
                    for (int i = 1; i <= n; i++)
                    {
                            scanf("%s",str + 1);
                            int len = strlen(str + 1);
                            int fir = str[1] - 'a' + 1 , lst = str[len] - 'a' + 1;
                            merge(fir,lst);        
                            addedge(fir,lst);
                            in[lst]++; out[fir]++;
                            s.insert(fir); s.insert(lst);
                    }        
                    bool connect = false;
                    int sz = (int)s.size();
                    for (int i = 1; i <= 26; i++) connect |= (size[i] == sz);
                    if (!connect)
                    {
                            printf("The door cannot be opened.
    ");
                            continue;
                    }
                    bool flag = true;
                    for (set<int> :: iterator it = s.begin(); it != s.end(); it++) flag &= (in[*it] == out[*it]);
                    if (flag)
                    {
                            printf("Ordering is possible.
    ");
                            continue;
                    }
                    int s1 = 0 , s2 = 0;
                    for (set<int> :: iterator it = s.begin(); it != s.end(); it++)
                    {
                            s1 += ((in[*it] - out[*it]) == 1);
                            s2 += ((out[*it] - in[*it]) == 1);
                            if (abs(in[*it] - out[*it]) >= 2) s1 = M;
                    }
                    if (s1 == s2 == 1) printf("Ordering is possible.
    ");
                    else printf("The door cannot be opened.
    ");
            }
            
            return 0;
        
    }
  • 相关阅读:
    区间DP——石子合并
    线性DP-最短编辑距离、编辑距离
    生成树协议
    交换机技术
    以太网原理
    接口知识点
    目前在中国有影响的几种现场总线比较
    委托
    C#有关继承知识点
    C#数组总结
  • 原文地址:https://www.cnblogs.com/evenbao/p/9508275.html
Copyright © 2011-2022 走看看