poj1270 拓扑序(DFS)

题意:给出将会出现的多个字母,并紧接着给出一部分字母的大小关系,要求按照字典序从小到大输出所有符合上述关系的排列。

拓扑序,由于需要输出所有排列,所以需要使用 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!='\n'))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("\n");
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("\n");
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=='\n')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=='\n')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 }
View Code

 

转载于:https://www.cnblogs.com/cenariusxz/p/4797669.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值