博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ZOJ_1589 Professor John 深度优先搜寻

Posted on 2010-08-11 20:42  还好  阅读(1286)  评论(3编辑  收藏  举报

先看题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1589

转化一下题目意思就是说给定几组大小关系(26个大写字母),然后输出根据这些大小关系可以推导出的其他所有的大小关系!例如A<B,C>B,C<D,则可以推导出A<C,A<D,B<D。

这是一道很不错的深度优先算法题,通过这道题个人对深度优先算法又有了进一步的理解!

解题思路:将26个大写字母的大小关系,转化成数字0到25的大小关系!定义两个bool型的数组:previous[26][26],用来记录已知的大小关系,now[26][26]用来记录最后推导出来的大小关系,当然也包括已知的大小关系!再定义一个bool型的数组isVisit[26],用来记录那些点已经被访问过!最后就是再定义一个int型数组a[26],用来记录在每次遍历过程中所经过的点!

这里有一点需要注意的就是:假如刚开始从数字0开始遍历,那么凡是能从0遍历到的数字,当从0遍历结束之后,是不需要再从这些点开始遍历的!这也是数组

isVisit[26]的作用!

下面是我的C++代码,RUN TIME:20MS,RUN MEMEORY:184KB

 

代码
#include<iostream>
using namespace std; 

const int N 26;
bool previous[N][N];
bool now[N][N];
int* a=new int[N];
bool isVisit[N];

void DFS(int len, int start)
{
   
for (int i = 0; i < N; i++)
   {
      
if (i == start) continue;

      
if (previous[start][i])
      {
        
for (int j = 0; j < len; j++)
        {
            now[a[j]][i] 
= true
            
//cout<<a[j]<<" < "<<i<<endl;
        }
        a[len] 
= i;
        len
++;
        isVisit[i]
=true;
        DFS(len, i);
        len
--;
      }
    }

}

int main(void)
{
    
int i,j,m,n,count;
    
char a1,b1,c1;
    cin
>>n;
    
for(int k=1;k<=n;k++)
    {
        
for (i = 0; i < N; i++)
        {
            isVisit[i]
=false;
            
for (j = 0; j < N; j++)
            {
                previous[i][j] 
= false;
                now[i][j] 
= false;
            }
        }
        cin
>>m;
        
for (i = 0; i < m; i++)
        {
            cin
>>a1>>b1>>c1;
            
if(b1=='<')
            {
                previous[a1
-'A'][c1-'A']=true;//将对应的字母大小关系转换成数字的大小关系
            }
            
else
            {
                previous[c1
-'A'][a1-'A']=true;//将对应的字母大小关系转换成数字的大小关系
            }
        }

        
for(i=0;i<N;i++)
        {
            
if(!isVisit[i])
            {
                a[
0]=i;
                DFS(
1, i);
            }
        }

        cout
<<"Case "<<k<<":"<<endl;
        count
=0;
        
for(i=0;i<N;i++)
        {
            
for (j = 0; j < N; j++)
            {
                
if(now[i][j]&&!previous[i][j])
                {
                    cout
<<char(i+'A')<<"<"<<char(j+'A')<<endl;
                    count
++;
                }
            }
        }
        
if(count==0)
        {
            cout
<<"NONE"<<endl;
        }
    }
    
return -1;
}