uva10129 PlayOnWords(并查集,欧拉回路)

判断无向图是否存在欧拉回路,就是看度数为奇数的点有多少个,如果有两个,那么以那分别两个点为起点和终点,可以构造出一条欧拉回路,如果没有,就任意来,否则,欧拉回路不存在。

首先用并查集判断连通,然后统计度数。

#include<cstdio>
#include<cstring>
#include<vector>
//#include<algorithm>
//#define local
using namespace std;

const int maxl = 26;
const int maxn = 1e3 + 3;
int p[maxl];
bool used[maxl];//出现过的字符

char s[maxn];

int Find(int x) {return p[x] == x ? x : p[x] = Find(p[x]); }

char last(char *p)
{
   while(*(++p));
   return *(p-1);
}

int deg[maxl];//出度 - 入度
#define ID(c) (c-'a')
int main()
{
#ifdef local
    freopen("in10129.txt","r",stdin);
#endif // local
   int T,N;
   scanf("%d",&T);
   while(T--) {
      memset(used,false,sizeof(used));
      memset(deg,0,sizeof(deg));
      int cc = 26;
      for(int i = 0; i < maxl; i ++) { p[i] = i; }
      scanf("%d", &N);
      while(N--){
         scanf("%s",s);
         int u = ID(*s), v = ID(last(s));
         deg[u]++; deg[v]--;
         used[u] = used[v] = true;
         int s1 = Find(u), s2 = Find(v);
         if(s1 != s2) {
            p[s1] = s2; cc--;
         }
      }
      bool ok = false;
      for(int i = 0; i < maxl; i ++) {
         if(!used[i]) cc--;
      }
      int odd[maxl] = {0},top = 0;
      if(cc == 1){
         for(int i = 0; i < maxl; i ++) if(deg[i]) {
            odd[top++] = deg[i];
         }
         if(top == 2 && (odd[0] == 1 || odd[1] == 1) ) ok = true;//入度sum = 出度sum
         else if(top == 0) ok = true;
      }
      if(ok) printf("Ordering is possible.
");
      else printf("The door cannot be opened.
");
   }
   return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4597641.html