HDU 1116 Play on Words(有向欧拉判断)

题目链接

题意:给出一些单词,问全部单词能否首尾相连

直接 将每一个单词第一个和最后一个字母建立一条有向边,保证除了首尾两个出入度不相等,其他的要保证相等。还有一个条件就是 首尾两个出入度差为1

同时并查集判连通

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <algorithm>
  6 using namespace std;
  7 const int Max = 100000 + 10;
  8 struct Node
  9 {
 10     int x, y;
 11 };
 12 char str[Max];
 13 Node node[Max];
 14 int indegree[30], outdegree[30];
 15 int father[30], vis[30];
 16 int find_father(int x)
 17 {
 18     if (x == father[x])
 19         return x;
 20     return father[x] = find_father(father[x]);
 21 }
 22 int unionset(int x, int y)
 23 {
 24     x = find_father(x);
 25     y = find_father(y);
 26     if (x == y)
 27         return false;
 28     father[y] = x;
 29     return true;
 30 }
 31 int main()
 32 {
 33     int T, n;
 34     scanf("%d", &T);
 35     while (T--)
 36     {
 37         scanf("%d", &n);
 38         memset(indegree, 0, sizeof(indegree));
 39         memset(outdegree, 0, sizeof(outdegree));
 40         memset(vis, 0, sizeof(vis));
 41         for (int i = 0; i < 30; i++)
 42             father[i] = i;
 43         int setcnt = 0;
 44         for (int i = 1; i <= n; i++)
 45         {
 46             scanf("%s", str);
 47             node[i].x = str[0] - 'a';
 48             node[i].y = str[ strlen(str) - 1] - 'a';
 49             indegree[node[i].y]++;
 50             outdegree[node[i].x]++;
 51             vis[node[i].x] = 1;
 52             vis[node[i].y] = 1;
 53             if (unionset(node[i].x, node[i].y))
 54             {
 55                 setcnt++;
 56             }
 57         }
 58         int numcnt = 0;
 59         for (int i = 0; i < 26; i++)
 60         {
 61             if (vis[i])
 62                 numcnt++;
 63         }
 64         if (setcnt != (numcnt - 1))
 65         {
 66             printf("The door cannot be opened.\n");
 67             continue;
 68         }
 69         if (n == 1)
 70         {
 71             printf("Ordering is possible.\n");
 72             continue;
 73         }
 74         int x = 0, y = 0, z = 0;
 75         for (int i = 0; i < 26; i++)
 76         {
 77             if (vis[i] && indegree[i] != outdegree[i])
 78             {
 79                 if (indegree[i] == outdegree[i] + 1) //
 80                     x++;
 81                 else if (indegree[i] + 1 == outdegree[i]) //
 82                     y++;
 83                 else
 84                     z++;
 85             }
 86         }
 87         if (z)
 88             printf("The door cannot be opened.\n");
 89         else if ( (x == 1 && y == 1) || (x == 0 && y == 0) ) // 出入度不相等 且 差为1, 或者 是环
 90             printf("Ordering is possible.\n");
 91         else
 92             printf("The door cannot be opened.\n");
 93         /*
 94         int cnt = 0, sum = 0;
 95         for (int i = 0; i < 26; i++)
 96         {
 97             if (indegree[i] > 0 || outdegree[i] > 0)
 98             {
 99                 sum++;
100                 if (indegree[i] == outdegree[i])
101                     cnt++;
102             }
103         }
104         if (cnt == sum || ( sum > 2 && sum - cnt == 2))
105             printf("Ordering is possible.\n");
106         else
107             printf("The door cannot be opened.\n");
108             */
109     }
110     return 0;
111 }
View Code

 

posted @ 2016-04-04 22:00  zhaop  阅读(156)  评论(0编辑  收藏  举报