zoukankan      html  css  js  c++  java
  • UVa 10129 (并查集 + 欧拉路径) Play on Words

    题意:

    有n个由小写字母的单词,要求判断是否存在某种排列使得相邻的两个单词,前一个单词末字母与后一个单词首字母相同。

    分析:

    将单词的两个字母看做节点,则一个单词可以看做一条有向边。那么题中所求的排列就等价于该有向图中是否存在欧拉路径。

    在判断之前,首先要确定这个图是连通的,代码中用并查集来实现。

    回顾一下存在欧拉路径的条件,全都是偶点或者有且仅有两个奇点。我们用deg来记录每个点的度,出度为1,入度为-1。

    程序中判断存在欧拉路径的条件就是:deg全为0 或者 有两个不为0的,其中一个为1一个为-1

    used记录某个字母是否出现过。

     1 //#define LOCAL
     2 #include <vector>
     3 #include <cstdio>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int maxn = 1000 + 10;
     8 char word[maxn];
     9 int pa[256], deg[256], cc, used[256];
    10 
    11 int find(int a)
    12 { return pa[a] == a ? a : pa[a] = find(pa[a]); }
    13 
    14 int main(void)
    15 {
    16     #ifdef LOCAL
    17         freopen("10129in.txt", "r", stdin);
    18     #endif
    19 
    20     int T, n;
    21     scanf("%d", &T);
    22     while(T--)
    23     {
    24         memset(used, 0, sizeof(used));
    25         memset(deg, 0, sizeof(deg));
    26         for(int i = 'a'; i <= 'z'; ++i)
    27             pa[i] = i;
    28         cc = 26;    //Á¬Í¨¿éµÄÊýÁ¿ 
    29 
    30         scanf("%d", &n);
    31         for(int i = 0; i < n; ++i)
    32         {
    33             scanf("%s", word);
    34             char c1 = word[0];
    35             char c2 = word[strlen(word) - 1];
    36             used[c1] = used[c2] = 1;
    37             deg[c1]++;    deg[c2]--;
    38             int p1 = find(c1);
    39             int p2 = find(c2);
    40             if(p1 != p2)
    41             {
    42                 cc--;
    43                 pa[p1] = p2;
    44             }
    45         }
    46 
    47         vector<int> d;
    48         for(int i = 'a'; i <= 'z'; ++i)
    49         {
    50             if(!used[i]) --cc;
    51             else if(deg[i])    d.push_back(i);
    52         }
    53         bool ok = false;
    54         if(cc == 1 && (d.empty() || (d.size() == 2 && (deg[d[0]] == 1 || deg[d[0]] == -1)))) ok = true;
    55         if(ok)    puts("Ordering is possible.");
    56         else puts("The door cannot be opened.");
    57     }
    58 
    59     return 0;
    60 }
    代码君
  • 相关阅读:
    Dynamics CRM命令栏定制基础知识及手动编辑customization.xml实例
    在Dynamis CRM中打造一键保存关闭刷新案例的功能
    Dynamics CRM 客户端程序开发:自定义系统标准按钮的可用性
    cmd 获取当前登录的用户和远程连接的用户
    发生系统错误 6118
    Windows 批量修改文件后缀名
    dos命令创建批处理脚本
    3389连接痕迹清除
    创建超级隐藏用户
    lcx 内网转发
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3991509.html
Copyright © 2011-2022 走看看