Play on Words HDU - 1116(欧拉路判断 + 并查集)

Posted wtsruvf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Play on Words HDU - 1116(欧拉路判断 + 并查集)相关的知识,希望对你有一定的参考价值。

题意:

  给出几个单词,求能否用所有的单词成语接龙

解析:

  把每个单词的首字母和尾字母分别看作两个点u 和 v,输入每个单词后,u的出度++, v的入度++

  最后判断是否能组成欧拉路径 或 欧拉回路,当然首先要判断一下是否是一个连通块,用并查集维护就好了,当然有自环,所以用一个vis标记一下这个点是否出现过

看代码就懂了

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <bitset>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define pd(a) printf("%d
", a);
#define plld(a) printf("%lld
", a);
#define pc(a) printf("%c
", a);
#define ps(a) printf("%s
", a);
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 10010, INF = 0x7fffffff, LL_INF = 0x7fffffffffffffff;
int head[maxn], in[maxn], out[maxn], f[maxn], vis[maxn];
int n, m, cnt;
set<int> s;

int find(int x)
{
    return f[x] == x ? x : (f[x] = find(f[x]));
}

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        s.clear();
        mem(in, 0);
        mem(out, 0);
        mem(vis, 0);
        for(int i = 1; i <= 30; i++) f[i] = i;
        string str;
        cin >> n;
        for(int i = 1; i <= n; i++)
        {
            cin >> str;
            int u = str[0] - a + 1;
            int v = str[str.size() - 1] - a + 1;
            int l = find(u);
            int r = find(v);
            vis[u] = vis[v] = 1;
            if(l != r) f[l] = r;
            out[u]++;
            in[v]++;
        }
        int cnt1 = 0, cnt2 = 0, flag = 0, cnt = 0;
        for(int i = 1; i <= 26; i++)
        {
            int x = find(i);
            if(vis[x]) s.insert(x);
            if(in[i] != out[i])
                flag = 1, cnt++;
            if(in[i] == out[i] + 1)
                cnt1++;
            else if(in[i] + 1 == out[i])
                cnt2++;
        }
        if(s.size() != 1)
        {
            cout << "The door cannot be opened." << endl;
            continue;
        }
        if(cnt != 2 && cnt != 0)
        {
            cout << "The door cannot be opened." << endl;
            continue;
        }
        if(cnt1 == 1 && cnt2 == 1 || flag == 0)
            cout << "Ordering is possible." << endl;
        else
            cout << "The door cannot be opened." << endl;

    }
    return 0;
}

 

以上是关于Play on Words HDU - 1116(欧拉路判断 + 并查集)的主要内容,如果未能解决你的问题,请参考以下文章

hdu1116 Play on Words--并查集&网络流

hdu 1116 Play on Words 欧拉路径+并查集

Play on Words HDU - 1116(欧拉路判断 + 并查集)

UVA 10129 Play on Words

Play on Words UVA - 10129

POJ 1386 Play on Words