题目描述
当我们知道一组大小关系之后,可判断所有关系是否都能成立,即关系间没有矛盾。例如:A<B, A<C, B<C 通过这组关系我们可以得到A<B<C ,所有关系都成立,没有矛盾。
若 A<B, B<C, C<A 通过前两个关系我们得到 A<B<C ,这个关系与C<A矛盾,所有关系不能同时成立。
现在我们知道m个关系,请判断这m个关系是否能成立,成立输出“YES”,否则输出“NO”。
输入
多组数据,每组数据如下:
第一行有一个数字m。 m代表m组关系(1<=m<=400),接下来m行每行有一个关系,用两个不同的字母和一个符号表示。(输入保证字母在‘A’-‘Z’之间,关系符号只有 > , <)
输出
对于每组数据输出“YES”或“NO”.
样例输入
3
A<B
A<C
B<C
3
A<B
B<C
C<A
样例输出
YES
这道题比赛的时候开始就有了思路,不过整整做了一个半小时才做完, 中间各种出错吧,一直在调试,这道题的思路是用一个邻接表和深搜解决!
具体怎么做代码中会有注释 光说太罗嗦
#include<stdio.h>
#include<stdlib.h>
struct temp{
char k;
struct temp *next;
};//这是邻接表的存储结构,邻接表后面只存正确且比自己大的字母
struct cmp{
struct temp *s;
}b[100];//这是邻接表的头 ,在这有一个技巧就是A~Z的ascii值是从65~90的这样b[65]~b[90]直接代表了
//b[A]~b[Z]
struct temp * f()//这个函数是申请空间
{
struct temp *p;
return p = (struct temp *)malloc(sizeof(struct temp));
}
int DFS(struct temp *w, char z)//这个是深搜函数,深搜的思路是把传入的两个字母较大的那个字母开始搜索
//如果在深搜过程中找到了较小的值 则返回值为零 找不到返回一
{
while(w != NULL)
{
if( w -> k == z )
return 0;
else if(DFS(b[w -> k].s, z) == 0)
return 0;
w = w -> next;
}
return 1;
}
int main()
{
int n, i, k, ok;
struct temp *p, *q;
char x, y, ch, a[5];
while(scanf("%d", &n) != EOF)
{
for(i = 60; i < 100; i++)
b[i].s = NULL;
ok = 1;
for(i = 0; i < n; i++)
{
scanf("%s", a);
if(0 == ok)//如果中间出现错误下面就不用判断了直接停止就可以了
continue;//我得思路这一句一定得加,否则提交会超时,比赛时加了这句直接过了
//不过刚刚提交时少了这句超时,因为是递归 已经错了 还继续往下的话会把时间延长很多
x = a[0]; y = a[2]; ch = a[1];
if(ch == '<')
{
if(DFS(b[y].s, x))
{
p = f();
p -> k = y;
q = b[x].s;
b[x].s = p;
p -> next = q;
}
else
{
ok = 0;
}
}
else if( ch == '>' )
{
if( DFS(b[x].s, y) )
{
p = f();
p -> k = x;
q = b[y].s;
b[y].s = p;
p -> next = q;
}
else
{
ok = 0;
}
}
}
if(1 == ok)
printf("YES\n");
else if(0 == ok)
printf("NO\n");
}
return 0;
}