题意:给出将会出现的多个字母,并紧接着给出一部分字母的大小关系,要求按照字典序从小到大输出所有符合上述关系的排列。
拓扑序,由于需要输出所有排列,所以需要使用 dfs ,只要点从小到大遍历就可以实现字典序排列了。

1 #include<stdio.h>
2 #include<string.h>
3
4 int ma[26][26],id[26],vis[26],v[26],n;
5
6 char s[10],ans[50];
7
8 char read(){
9 char c=getchar();
10 while((c>'z'||c<'a')&&(c!='
'))c=getchar();
11 return c;
12 }
13
14 void dfs(int ss,int t){
15 ans[t]=ss+'a';
16 v[ss]=1;
17 if(t==n){
18 for(int i=1;i<=n;++i)printf("%c",ans[i]);
19 printf("
");
20 v[ss]=0;
21 return;
22 }
23 int que[50],cnt=0;
24 for(int i=0;i<26;++i){
25 if(ma[ss][i])id[i]--;
26 if(vis[i]&&!id[i]&&!v[i])que[++cnt]=i;
27 }
28 for(int i=1;i<=cnt;++i)dfs(que[i],t+1);
29 for(int i=0;i<26;++i)if(ma[ss][i])id[i]++;
30 v[ss]=0;
31 }
32
33 int main(){
34 int ccnt=0;
35 while(scanf("%s",s)!=EOF){
36 if(ccnt++)printf("
");
37 memset(ma,0,sizeof(ma));
38 memset(id,0,sizeof(id));
39 memset(vis,0,sizeof(vis));
40 memset(v,0,sizeof(v));
41 n=0;
42 vis[s[0]-'a']=1;
43 n++;
44 char c1,c2;
45 while(c1=getchar()){
46 if(c1=='
')break;
47 if(c1>'z'||c1<'a')continue;
48 int cc=c1-'a';
49 if(!vis[cc]){
50 vis[cc]=1;
51 n++;
52 }
53 }
54 bool f=1;
55 while(f){
56 c1=read();
57 if(c1=='
')break;
58 c2=read();
59 int cc1=c1-'a',cc2=c2-'a';
60 if(!ma[cc1][cc2]){
61 ma[cc1][cc2]=1;
62 id[cc2]++;
63 }
64 }
65 for(int i=0;i<26;++i)if(vis[i]&&!id[i])dfs(i,1);
66 }
67 return 0;
68 }