• poj1386--Play on Words--欧拉路


    Description

    给你若干个单词,一个单词能拼接到前一个单词的标准是:此单词的首字母和前一个单词的尾字母相同。

    Sample Input

    3
    2
    acm
    ibm
    3
    acm
    malform
    mouse
    2
    ok
    ok
    

    Sample Output

    The door cannot be opened.
    Ordering is possible.
    The door cannot be opened.

    题解:

      构图:每个单词对应一条有向边,从此单词的首字母连向尾字母。如果其中存在欧拉路,说明可以拼接成链(欧拉通路)或环(欧拉回路)。

      首先存储字母出现的信息,因为是多组数据,注意每次要初始化记录数组。

      同时用used数组标记该字母是否出现在图中,in数组和out数组分别记录入度和出度。

      用一个并查集对整个构成的图做合并处理,判断此图是否没有孤立的点,如果有,说明不连通,需要输出“The door cannot be opend."

      如果整张图联通,进一步遍历这张图。

      接下来判断是否是欧拉路:

      1.如果有任何一个点的出入度之差大于1,就不是欧拉路;

      2.记录出入度不相等的点,如果入度-出度=1的点超过1个,说明终点超过1个,不是欧拉路;

      3.记录出入度不相等的点,如果出度-入度=1的点超过1个,说明起点超过了1个,也不是欧拉路。

      1 #include<algorithm>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<iostream>
      6 using namespace std;
      7 const int maxn=100009;
      8 
      9 int n,m,in[maxn],out[maxn],fa[maxn];
     10 bool used[maxn];
     11 
     12 void init()
     13 {
     14     memset(used,0,sizeof(used));
     15     memset(in,0,sizeof(in));
     16     memset(out,0,sizeof(out));
     17     for(int i=1;i<=n;i++)
     18         fa[i]=i;
     19 }
     20 
     21 int find(int x)
     22 {
     23     if(x!=fa[x])
     24         fa[x]=find(fa[x]);
     25     return fa[x];
     26 }
     27 
     28 void uni_set(int x,int y)
     29 {
     30     int u=find(x),v=find(y);
     31     if(u==v)
     32         return;
     33     fa[u]=v;
     34 }
     35 
     36 bool judge_eular()
     37 {
     38     int sta=0,end=0;
     39     for(int i=1;i<=26;i++)
     40     {
     41         if(used[i])
     42         {
     43             if(abs(in[i]-out[i])>1)return 0;
     44             if(in[i]-out[i]==1)
     45             {
     46                 end++;
     47                 if(end>1)return 0;
     48             }
     49             if(out[i]-in[i]==1)
     50             {
     51                 sta++;
     52                 if(sta>1)return 0;
     53             }
     54         }
     55     }
     56     return 1;
     57 }
     58 
     59 int main()
     60 {
     61     int T;
     62     scanf("%d",&T);
     63     while(T--)
     64     {
     65         scanf("%d",&n);
     66         init();
     67         int tmp;
     68         char a[1009];
     69         for(int i=1;i<=n;i++)
     70         {
     71             scanf("%s",a);
     72             int len=strlen(a);
     73             int u=a[0]-'a'+1, v=a[len-1]-'a'+1;
     74             in[v]++;out[u]++;
     75             used[u]=used[v]=1;
     76             tmp=v;
     77             uni_set(u,v);
     78         }
     79         tmp=find(tmp);
     80         bool ok=1;
     81         for(int i=1;i<=26;i++)
     82         {
     83             if(used[i]&&tmp!=find(i))
     84             {
     85                 printf("The door cannot be opened.
    ");
     86                 ok=0;
     87                 break;
     88             }
     89         }
     90         if(ok)
     91         {
     92             if(!judge_eular())
     93             {
     94                 printf("The door cannot be opened.
    ");
     95                 ok=0;
     96             }
     97             else
     98             {
     99                 printf("Ordering is possible.
    ");
    100                 ok=1;
    101             }
    102         }
    103     }
    104     return 0;
    105 }
    View Code
  • 相关阅读:
    洛谷 P1567 统计天数【最长上升子序列/断则归一】
    洛谷 P3742 umi的函数【构造】
    洛谷 P1036 选数【背包型DFS/选or不选】
    nyoj zb的生日【背包型DFS/选or不选】
    POJ 3628 Bookshelf 2【背包型DFS/选or不选】
    【AHOI2013复仇】从一道题来看DFS及其优化的一般步骤和数组分层问题【转】
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes【取回文数/数论/字符串】
    洛谷 P1004 方格取数 【多线程DP/四维DP/】
    Codeforces Round #449 (Div. 2) B. Chtholly's request【偶数位回文数】
    Codeforces Round #449 (Div. 2) A. Scarborough Fair【多次区间修改字符串】
  • 原文地址:https://www.cnblogs.com/Beckinsale/p/7604806.html
Copyright © 2020-2023  润新知