题目:用(A,B)表示B是A的1代学生。如果没有人是A的老师,那么A称为祖师爷。输入一组师生关系,求出师生树的总数,并分别输出成员:师祖及各代学生。
ps:字符A与B是大写或小写字母,大小写有别;
输入: 输出:
5 Case 1:
A B 1:A B C E
B C 2:D E
A E Tatal=2
B E
D E
思路: 求师生树的成员,首先应该知道师祖元素,师祖元素通过枚举没人是其老师而获知,然后寻找与师祖有关系的学生,可通过传递闭包。
代码:
#include <iostream>
#include <cstring>
using namespace std;
#define MAXN 60
int e,count;
int G[MAXN][MAXN];
int visit[MAXN];
void solve()
{
//传递闭包
for(int k=0;k<60;k++)
for(int i=0;i<60;i++)
for(int j=0;j<60;j++)
if(G[i][k]&&G[k][j])
G[i][j]=1;
//枚举祖先元素
int num=0;
for(int k=0;k<60;k++)
{
bool flag=true;
for(int i=0;i<60;i++)
if(G[i][k]||!visit[k])//两个判别条件缺一不可
{
flag=false;
break;
}
if(flag)//若k是一个祖先
{
cout<<++num<<":";
cout<<char('A'+k);
for(int i=0;i<60;i++)
if(G[k][i])
cout<<" "<<char('A'+i);
cout<<endl;
}
}
count=num;
}
int main()
{
int cas=0;
char x,y;
while(cin>>e&&e)
{
memset(G,0,sizeof(G));
memset(visit,0,sizeof(visit));
count=0;
for(int i=0;i<e;i++)
{
cin>>x>>y;
int u=x-'A',v=y-'A';
G[u][v]=1;
visit[u]=1;
visit[v]=1;
}
cout<<"Case"<<++cas<<":"<<endl;
solve();
cout<<"Total="<<count<<endl;
}
}