hdu1116

这题想了很久,还是没做出来,看了一下网上的题解,原来是把字母当成点,用
单词代表关系,这样建立并查集,检查连通性。如果连通,则检查是否存在欧拉
通路,注意欧拉回路也是欧拉通路一种,离散数学的知识:
要么所有点入度等于出度;
要么有且只有两个点,一个是入度比出度大一,另一个一个是出度比入度大一,
其余的点都相等;

140ms代码

#include<iostream>
#include<string>
typedef struct charter
{
 long int in;
 long int out;
 int father;
}charter;
charter bin[27];
int v[27];
int find(int x)
{
 while(x!=bin[x].father)
  x=bin[x].father;
 return x;
}

int merge(int x,int y)
{
 int fx,fy;
 fx=find(x);
 fy=find(y);
 if(fx!=fy)
 {
  bin[fy].father=fx;
 }
 return 0;
}

int main()
{
 int t,i,flag,iflag,oflag,x,y,root;
 long int n;
 char c[1002];
 scanf("%d",&t);
 while(t--)
 {
  scanf("%ld",&n);
  flag=iflag=oflag=root=0;
  for(i=0;i<26;i++)
  {
   bin[i].father=i;
   bin[i].in=0;
   bin[i].out=0;
   v[i]=0;
  }
  for(i=0;i<n;i++)
  {
   scanf("%s",c);
   x=c[0]-'a';
   bin[x].out++;
   y=c[strlen(c)-1]-'a';
   bin[y].in++;
   merge(x,y);
   v[x]=v[y]=1;
  }
  for(i=0;i<26;i++)
  {
   if(v[i]==1&&bin[i].father==i)
    root++;

  }
  if(root!=1)
  {
   printf("The door cannot be opened.\n");
  }
  else
  {
   for(i=0;i<26;i++)
   {
    if(bin[i].in==bin[i].out+1)
    {
     iflag++;
    }
    else if(bin[i].out==bin[i].in+1)
    {
     oflag++;
    }
    else if((bin[i].in>bin[i].out+1)||(bin[i].out>bin[i].in+1))
    {
     flag=1;
     break;
    }
   }
   if(flag!=1&&((iflag==0&&oflag==0)||(iflag==1&&oflag==1)))
   {
    printf("Ordering is possible.\n");
   }
   else
   {
    printf("The door cannot be opened.\n");
   }
  }

 }

 return 0;
}

 

你可能感兴趣的:(return,include,离散数学,单词,father)