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;
    }
  • 相关阅读:
    hdu 2444 交叉染色判断二分图+二分最大匹配
    uva 交叉染色法10004
    poj 3177&&3352 求边双联通分量,先求桥,然后求分量( 临界表代码)
    poj 3177&&poj 3352加边构双联通(有重边)用tarjan 模板求的
    poj 3006水题打素数表
    POJ 3352 无向图边双连通分量,缩点,无重边
    hdu 1430 魔板 康托展开 + 很好的映射
    D. Artsem and Saunders 数学题
    vijos P1412多人背包 DP的前k优解
    1475 建设国家 DP
  • 原文地址:https://www.cnblogs.com/sykline/p/10567600.html
Copyright © 2011-2022 走看看