• POJ1270 toposort+DFS+回溯


    题目链接:http://poj.org/problem?id=1270

    这道题其实就是求所有满足条件的topo序,我们考虑到给定的字符是确定的,也就是他们的长度都是一样的,所以为了得到所有的情况,我们可以考虑深度优先搜素和dfs解答树上的回溯。首先,我们从任何一个入度为0的点开始dfs,将这个点的入度-1,防止下一层的搜索中搜到这个点,再更新所有这个点可到达的点的入度,完成这些状态更新之后dfs解答树进入下一层搜索,直到深度值等于串长,输出topo序。回溯的过程中我们需要将之前修改的所有的状态都修改回来。读入的时候要考虑到一次性读入一行,然后进行空格的处理。

    代码如下:

     1 #include<cstdio> 
     2 #include<algorithm>
     3 #include<string.h>
     4 #include<map>
     5 using namespace std;
     6 const int maxn=25;
     7 int n,m,t;
     8 int vis[maxn],in[maxn],e[maxn][maxn];
     9 char s[100],h[maxn],ans[maxn];
    10 int cnt;
    11 void init()
    12 {
    13     memset(vis,0,sizeof(vis));
    14     memset(in,0,sizeof(vis));
    15     memset(ans,0,sizeof(ans));
    16     memset(e,0,sizeof(e));
    17 }
    18 void toposort(int dep)
    19 {
    20     if(dep==cnt)
    21     {
    22         printf("%s
    ",ans);
    23         return ;
    24     }
    25     for(int i=0;i<cnt;i++)
    26     {
    27         if(in[i]==0&&!vis[i])//只要找到入度为0而且不在topo序中的点就开始搜索,至于回溯和标记则是在递归中进行 
    28         {
    29             vis[i]=1;
    30             ans[dep]=h[i];
    31             for(int j=0;j<cnt;j++)
    32                 if(e[i][j])in[j]--;
    33             toposort(dep+1);
    34             vis[i]=0;
    35             for(int j=0;j<cnt;j++)
    36                 if(e[i][j])in[j]++;//回溯过程 
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     //freopen("input.txt","r",stdin);
    43     //freopen("output.txt","w",stdout);
    44     //std::ios::sync_with_stdio(false);
    45     while(gets(s))//一次性读取一行字符串在处理 
    46     {
    47         cnt=0;
    48         int len=strlen(s);
    49         map<char ,int > mp;
    50         init();
    51         for(int i=0;i<len;i++)
    52         {
    53             if(s[i]>='a'&&s[i]<='z')//读掉空格 
    54             {
    55                 h[cnt++]=s[i];
    56             }
    57         }     
    58             sort(h,h+cnt);//为了保证最终的topo序是按照字典序输出的,需要给字符集排个序,这样搜索将会变得有序    
    59             for(int i=0;i<cnt;i++)
    60             {
    61                 mp[h[i]]=i;//将字符集转化成整数集 
    62              }
    63              gets(s);
    64              len=strlen(s);
    65              int tmp1,tmp2;
    66              bool flag=0;//由于是成对出现的,通过对flag的翻转可以确认目前得到的是成对的第一个数还是第二个数 
    67              for(int i=0;i<len;i++)
    68              {
    69                  if(s[i]>='a'&&s[i]<='z')
    70                  {
    71                      if(!flag)
    72                      {
    73                          flag=1;
    74                          tmp1=mp[s[i]];//得到的是成对中的第一个数,并获取编号 
    75                       } 
    76                     else
    77                     {
    78                         tmp2=mp[s[i]];
    79                         flag=0;
    80                          e[tmp1][tmp2]=1;
    81                          in[tmp2]+=1;
    82                      } 
    83                  }
    84               } 
    85          toposort(0);
    86          printf("
    ");//注意每个结果之后有一个空行 
    87     }
    88 } 
  • 相关阅读:
    UIControl IOS控件编程 及UITextField的讲解
    ViewPager实现页面切换
    HDU 3788 和九度OJ 1006测试数据是不一样的
    的基本原理的面向对象的--------单个程序员必须查看
    hdu1796 How many integers can you find
    Android数据加载和Json解析——蓝本
    设计管理员表;webservice用于网络安全的高端内提供服务的
    how tomcat works 札记(两)----------一个简单的servlet集装箱
    新秀学习Hibernate——一个简单的例子
    在cocos2d-x在CCTableView使用控制
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12578377.html
Copyright © 2020-2023  润新知