zoukankan      html  css  js  c++  java
  • HDU1116(欧拉路径+并查集)

    题意:

    给出一些字符串,有这两个字符串,如果第一个字符串的最后一个字母和第二个字符串的第一个字母是一样的,则这两个字符串是可以连接在一起的。

    问给出的这些字符串能否串成一个环或者一整个链。

    思路:

    将头部看做是入度,将尾部看做是出度,如果是一个链的话那么

    链的头部那个字母:indegree = outdegree+1;

    链的尾部那个字母:indegree+1 = outdegree;

    中间出现的字母:indegree = outdegree;

    首先用并查集看看给出的这些链能不能连成一个连通分量,如果不是一个连通分量,那就一定不能连成一条链或者一个环。

    然后根据欧拉路径(欧拉回路)的入度和出度的性质来判断。

    欧拉路径:(百度百科)

    代码:

    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #include <iomanip>
    #define MAX 1000000000
    #define inf 0x3f3f3f3f
    #define FRE() freopen("in.txt","r",stdin)
    
    using namespace std;
    typedef long long ll;
    const int maxn = 1050;
    int n;
    int fa[30],vis[30],in[30],out[30];
    char str[maxn];
    
    int _find(int x)
    {
        return fa[x]==x ? x:fa[x] = _find(fa[x]);
    }
    
    void init()
    {
        for(int i=0; i<30; i++)
        {
            fa[i] = i;
            in[i] = out[i] = 0;
            vis[i] = 0;
        }
    }
    
    int main()
    {
        //FRE();
        int kase;
        scanf("%d",&kase);
        while(kase--)
        {
            init();
            scanf("%d",&n);
            for(int i=0; i<n; i++)
            {
                scanf("%s",str);
                int u = str[0]-'a',v = str[strlen(str)-1]-'a';
                in[u]++;
                out[v]++;
                vis[u] = vis[v] = 1;
                u = _find(u);
                v = _find(v);
                if(u != v)
                { fa[u] = v; }
            }
            int a=0,b=0,c=0,d=0;
            for(int i=0; i<26; i++)
            {
                if(vis[i] && fa[i]==i) { c++; }//首先得是一个连通分量才能连成一个环或者是一条链
                if(vis[i])
                {
                    if(in[i]==out[i]) continue;
                    else if(in[i]+1==out[i]) a++;//尾部的字母
                    else if(in[i]==out[i]+1) b++;//头部的字母
                    else d++;//中间不符合条件的情况
                }
            }
            //cout<<a<<"       "<<b<<"      "<<c<<endl;
            if(c>1 || d>0) { puts("The door cannot be opened."); }
            else if((a==0&&b==0) || (a==1&&b==1)) { puts("Ordering is possible."); }
            else { puts("The door cannot be opened."); }
        }
        return 0;
    }
  • 相关阅读:
    java学习day02---Spring Boot综合运用---活动模块
    java学习day01---GC
    课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    超码 候选码 主码 替换码 数据库 定义
    如何评测软件工程知识技能水平?
    创新产品的需求分析:未来的图书会是什么样子?
    案例分析:设计模式与代码的结构特性(桥接模式)
  • 原文地址:https://www.cnblogs.com/sykline/p/10567600.html
Copyright © 2011-2022 走看看