先看题目: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;
}
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;
}