zoukankan      html  css  js  c++  java
  • UVA 10129 Play on Words (欧拉通路)

    本文链接:http://www.cnblogs.com/Ash-ly/p/5398627.html

    题意:

      输入N(N <= 100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如:acm,malform,mouse)。每个单词最多包含 1000 个小写字母。输入中可以有重复的单词。

    思路:

      把一个字母的两端开成节点,单词看成有向边,若问题有借,当且仅当图中存在欧拉通路。所有只需要判断由单词而构建的图是否存在欧拉通路,由于是有向边,所以利用有向图欧拉通路的判定就可以了。

    判定条件

    (1):底图是连通图

    (2):可以有两个奇点,其中一个出度比入度大 1,另外一个入度比出度大1.

    对于条件1,在这里用并查集判断了,条件2统计每个点的出度,入度,加以判断就行了.

    代码:

    #include <stdio.h>  
    #include <string.h>  
    #include <iostream>  
    #include <math.h>
    #include <queue>
    #include <stack>
    #include <algorithm>
    using namespace std;  
    
    const int maxV = 29;
    int m;
    int pre[maxV + 7];
    int outdegree[maxV + 7];
    int indegree[maxV + 7];
    
    int Find(int x){return x == pre[x] ? x : pre[x] = Find(pre[x]); }//并查集的查找
    void initPre(){ for(int i = 0; i <= maxV; i++) pre[i] = i; }//初始化并查集的数组
    
    int mix(int x, int y)//并查集的合并
    {
        int fx = Find(x), fy = Find(y);    
        if(fx != fy) pre[fx] = fy;    
    }
    
    bool isConnct()//判断图是否连通,即所有的点都在一个集合里面
    {
        int cnt = 0;
        for(int i = 1; i <= maxV; i++)if( (outdegree[i] != 0 || indegree[i] != 0) && pre[i] == i) cnt++;
        if(cnt == 1)return true;
        return false;
    }
    
    bool isEulur()//是否存在欧拉通路
    {
        int cnt = 0;
        int flag = 0;
        for(int i = 1; i <= 26; i++)
            if((outdegree[i] != 0 || indegree[i] != 0) && (indegree[i] != outdegree[i]))//判断奇点,方法不唯一。
            {
                cnt++;
                flag += (indegree[i] - outdegree[i]);
                if(flag > 1 || flag < -1) return false;
            } 
        if(cnt == 0 || cnt == 2 && flag == 0) return true;
        return false;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &m);
            initPre();
            memset(indegree, 0, sizeof(indegree));
            memset(outdegree, 0, sizeof(outdegree));
            for(int i = 1; i <= m; i++)
            {
                char word[1000 + 7];
                scanf("%s", word);
                int u = word[0] - 'a' + 1;
                int len = strlen(word);
                int v = word[len - 1] - 'a' + 1;
                mix(u, v);
                ++outdegree[u];
                ++indegree[v];
            }
            if(isEulur() && isConnct())    printf("Ordering is possible.
    ");
            else                        printf("The door cannot be opened.
    ");
        }
        return 0;
    }
  • 相关阅读:
    IOS 开发 网络发展史(基础知识)
    加密详解
    IOS对接支付的流程
    App混合开发浅谈
    swift语法100
    2015年最新Android基础入门教程目录第二章:Android UI(User Interface)详解(已完结 40/40)
    2015年最新Android基础入门教程目录第一章:环境搭建与开发相关(已完结 10/10)
    Reactive开发
    tensorflow 安装
    Mask RCNN笔记
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5398627.html
Copyright © 2011-2022 走看看