[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.\n");
                        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.\n");
                        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.\n");
                else printf("The door cannot be opened.\n");
        }
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9508275.html