HDU 1116

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1116

题目大意:给你n个字符串,判断是否能够全部成功接龙    aXXXXb  - bXXXXc  - cXXXXf  - fXXXXe  ·······

整体思路:此题可看作一个有向图,每一个字符串看作一条边,首字母和尾字母分别是两点。判断此图是否存在欧拉通路,是否为连通图。若为存在欧拉通路的连通图,则满足题意。       

        所以我们首先可以利用并查集判断其是否为连通图,如不连通,直接输出门无法打开。然后由有向图的欧拉通路的判断条件,找出所有边的出度与入度。得出题目结果

        有向图是否存在欧拉路和欧拉回路判断条件:把一个点上的出度记为1、入度记为-1,这个点上所有的出度与入度相加即为它的度数。如果一个有向图只有一个度数为1的点、一个度数为-1的点,其他所有点的度数为0,那么存在欧拉路径,其中度数为1的是起点、度数为-1的是终点。当且仅当该图所有点的度数为0,存在欧拉回路。

代码: 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 30;

string s;
int in[maxn], ou[maxn], vis[maxn], f[maxn];
int find(int s)
{
    return s == f[s] ? s : find(f[s]);
}
int main()
{
    int T, n;
    cin >> T;
    while(T--) {
        cin >> n;
        memset(in,0,sizeof(in));
        memset(ou,0,sizeof(ou));
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <= maxn; i++) f[i] = i;
        int x, y, z;
        for(int i = 0; i < n; i++) {
            cin >> s;
            x = s[0] - 'a';
            y = s[s.size()-1] - 'a';
            in[x]++;
            ou[y]++;
            f[x] = f[y] = find(x);
            vis[x] = vis[y] = 1;
        }
        int r = 0;
        for(int i = 0; i < maxn; i++) {
            if(vis[i] && f[i] == i)
                r++;
        }
        if(r > 1) {   //1个根节点 
            cout << "The door cannot be opened." << endl;
            continue;
        }
        bool flag = false;
        x = 0, y = 0, z = 0;
        for(int i = 0; i < maxn; i++) {
            if(vis[i] && in[i] != ou[i]) {
                if(in[i] == ou[i]-1) x++;
                else if(in[i] == ou[i]+1) y++;
                else z++;
            }
        }
        if(z) {
            cout << "The door cannot be opened." << endl;
            continue; 
        }
        if((x == 1 && y == 1) || (x == 0 && y == 0)) {
            cout << "Ordering is possible." << endl;
        }else cout << "The door cannot be opened." << endl;
    }    
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/JiaaaaKe/p/11298275.html