poj 1386 Play on Words(欧拉回路…

来源:互联网 发布:知乎 大误 龙 编辑:程序博客网 时间:2024/06/05 09:01
题意 :N个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上面单词的末字母等于后一个盘子上面单词的首字母。请你编写一个程序,判断是否能达到这一要求。

思路:这道题,有一个很巧妙的转换,把点变成边。以26个字母作为顶点;对于每一个盘子,如果它的首字母为c1,末字母为c2,那么从c1向c2连一条有向边。如下图。然后判断图连通,再判断它是否为欧拉图PS:因为有重边,用边表建图时(在建图时加判断 用边表也可以),会超时,用邻接矩形比较好 因为只有26个点。


poj <wbr>1386 <wbr>Play <wbr>on <wbr>Words(欧拉回路+dfs)


//172K   313MS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define VM 30

int indeg[VM],outdeg[VM],mat[VM][VM],start;
bool vis[VM];

void dfs (int u)
{
    for (int i =0; i < 26; i ++)
       if (mat[u][i])
       {
           mat[u][i] = 0;
           dfs(i);
       }

}
bool cmp()
{
    inti,k,sum1,sum2,sum3;
    sum1 = sum2= sum3 = 0;
    for (i = 0;i < 26; i ++)
    {
       if (indeg[i] - outdeg[i] == 1)
           sum1 ++;
       if (outdeg[i] - indeg[i] == 1)
       {
           sum2 ++;
           start = i;
       }
       if (indeg[i] ==outdeg[i]&&indeg[i]!= 0)
           k = i;
       if (abs(indeg[i] - outdeg[i]) > 1)
           sum3 ++;
    }

    if (sum1> 1||sum2 > 1||sum3 >0)
       return false;
    if (sum2 ==0)
       start = k;
    returntrue;
}
int main ()
{
    intT,n;
    boolflag;
    charstr[1005];
    scanf("%d",&T);
    while (T--)
    {
       scanf ("%d",&n);
       memset (indeg,0,sizeof(indeg));
       memset (outdeg,0,sizeof(outdeg));
       memset (mat,0,sizeof(mat));
       memset (vis,false,sizeof(vis));
       while (n --)
       {
           scanf ("%s",str);
           int len = strlen(str);
           int u = str[0]-'a';
           int v = str[len-1]-'a';
           mat[u][v] = 1;
           indeg[v] ++;
           outdeg[u] ++;
       }
       flag = false;
       if (cmp ())
       {
           flag = true;
           dfs(start);
           for (int i = 0; i < 26; i ++)
               for (int j = 0; j < 26; j ++)
                   if (mat[i][j])
                   {
                       flag = false;
                       break;
                   }
       }
       if (flag)
           printf ("Ordering is possible.\n");
       else
           printf ("The door cannot be opened.\n");
    }
    return0;
}

原创粉丝点击