POJ 1386(欧拉路)

因为要求每个单词只是用一次,还要构成串,很容易想到欧拉路。

把单词抽象成一条边,首字母和末字母为边的两个端点,判断有向图欧拉路就行了

PS:注意判断连通性,判断连通性构图需要是双向的

 

View Code
 1 #include <cstdio>

 2 #include <cstdlib>

 3 #include <cstring>

 4 using namespace std;

 5 int in[30],out[30],sum,num,n,tt,st,len;

 6 bool map[30][30],vis[30];

 7 char ls[10000];

 8 void dfs(int u)

 9 {

10     vis[u]=true;

11     num++;

12     for(int i=1;i<=26;i++)

13         if(map[u][i]&&!vis[i]) dfs(i);

14 }

15 bool read()

16 {

17     memset(in,0,sizeof in);

18     memset(out,0,sizeof out);

19     memset(map,0,sizeof map);

20     memset(vis,0,sizeof vis);

21     sum=0;num=0;

22     scanf("%d\n",&n);

23     for(int i=1;i<=n;i++)

24     {

25         scanf("%s",ls+1);

26         len=strlen(ls+1);

27         out[ls[1]-'a'+1]++;

28         in[ls[len]-'a'+1]++;

29         map[ls[1]-'a'+1][ls[len]-'a'+1]=map[ls[len]-'a'+1][ls[1]-'a'+1]=1;

30     }

31 

32     for(int i=1;i<=26;i++) 

33     {

34         if(in[i]||out[i]) sum++;

35         if(out[i]) st=i;

36     }

37     memset(vis,0,sizeof vis);

38     dfs(st);//printf("st:%d\n",st);    //system("pause");

39     if(num==sum) {return true;}

40     else return false;

41 }

42 void go()

43 {

44     int a=0,b=0;

45     for(int i=1;i<=26;i++)

46     {

47         if(in[i]==out[i]+1) b++;

48         else if(out[i]==in[i]+1) a++;

49         else if(in[i]==out[i]) continue;

50         else 

51         {

52             printf("The door cannot be opened.\n");

53             return;

54         }

55     }

56     if(a<=1&&b<=1) printf("Ordering is possible.\n");

57     else printf("The door cannot be opened.\n");

58 }

59 int main()

60 {

61     scanf("%d",&tt);

62     while(tt--)

63     {

64         if(!read()) printf("The door cannot be opened.\n");

65         else go();

66     }

67     system("pause");

68     return 0;

69 }

 

 

你可能感兴趣的:(poj)