题目链接:http://210.43.24.243/problem.php?id=1308&csrf=0Ag2uYXQhlhOzjCRfMz44q2OcYldkWVn
题目描述
给你一些已经确定的元素之间的关系,请你判断是否能从这些元素关系中推断出其他的元素关系。
输入
输入的第一行是一个整数N,表示测试数据的组数。
每组输入首先是一个正整数m(m<=100),表示给定元素关系的个数。
接下来m行,每行一个元素关系,格式为:
元素1<元素2 或者 元素1>元素2
元素用一个大写字母表示,输入中不会包含冲突的关系。
输出
对于每组输入,第一行输出“Case d:”,d是测试数据的序号,从1开始。
接下来输出所有推断出的新的元素关系,按照字典序从小到大排序,格式为:
元素1<元素2
每个元素关系占一行,输入中给定的元素关系不要输出。
如果没有新的元素关系推断出来,则输出NONE。
样例输入
2
3
A<B
C>B
C<D
2
A<B
C<D
样例输出
Case 1:
A<C
A<D
B<D
Case 2:
NONE
利用Floyd的思想,运用其中中心代码进行求解,代码分析也不难,相当于是 珍珠BEAD 加强版
如果说A<B B<C 则可推出A<C 需要明白,输出是按照字典序的顺序输出,因此我们的判断也是从最小的开始,当存在A<B A<C B<C的情况时由A<B B<C 推出A<C,不可输出,也就是说我们需要一个标志数组,将样例给出的数据,进行标记。如果不存在有推出的关系式,则输出NONE
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[110][110];
int vis[27][27];
int main()
{
int T,t=1;
scanf("%d",&T);
while(T--)
{
int flag=0;
for(int i=1;i<=26;i++)
for(int j=1;j<=26;j++)
map[i][j]=0;//最开始互相不存在关系,故置0,存在关系,置1
memset(vis,-1,sizeof(vis));
int m;
scanf("%d",&m);
getchar();
for(int i=1;i<=m;i++)//将样例给予的关系置1
{
char a,b,c;
scanf("%c%c%c",&a,&b,&c);
if(b=='<')
{
map[a-64][c-64]=1;
vis[a-64][c-64]=1;
}
else
{
map[c-64][a-64]=1;
vis[c-64][a-64]=1;
}
getchar();
}
for(int k=1;k<=26;k++)
{
for(int i=1;i<=26;i++)
{
for(int j=1;j<=26;j++)
{
if(map[i][k]&&map[k][j]&&vis[i][j]!=1)//满足是新推断出的关系 vis数组置为0 map数组置为1
{
map[i][j]=1;
vis[i][j]=0;
}
}
}
}
printf("Case %d:\n",t++);
for(int i=1;i<=26;i++)
{
for(int j=1;j<=26;j++)
{
if(!vis[i][j])//vis数组为0 说明是新推出的关系,应当输出
{
printf("%c<%c\n",i+64,j+64);
flag=1;
}
}
}
if(flag==0)//标记输出位若为0,则没有推出新关系,输出NONE
printf("NONE\n");
}
return 0;
}