当我们知道一组大小关系之后,可判断所有关系是否都能成立,即关系间没有矛盾。
例如:A<B, A<C, B<C 通过这组关系我们可以得到A<B<C ,所有关系都成立,没有矛盾。
若 A<B, B<C, C<A 通过前两个关系我们得到 A<B<C ,这个关系与C<A矛盾,所有关系不能同时成立。
现在我们知道m个关系,请判断这m个关系是否能成立,成立输出“YES”,否则输出“NO”。
当我们知道一组大小关系之后,可判断所有关系是否都能成立,即关系间没有矛盾。
例如: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
NO
最近数据结构在讲图论的拓扑排序,正好刷个题来耍耍,简单拓扑排序。。
AC代码(有点挫(⊙o⊙)…,第一次写):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <stack>
using namespace std;
int indegree[26]; //记录入度
int visit[26]; //判断是否读入过
typedef struct node
{
char data;
struct node *p;
}list;
list zu[26];
void init() //初始化
{
for(int i=0; i<26; i++)
{
zu[i].p = NULL;
zu[i].data = (char)(i+65);
}
}
int topo(list zu[], int n) //拓扑排序 ,用的邻接表
{
stack<int> s;
node *xp;
for(int i=0; i<26; i++)
{
if(visit[i] && !indegree[i]) s.push(i);
}
int count = 0;
while(!s.empty())
{
int k = s.top(); s.pop(); count++;
for(xp = zu[k].p; xp; xp = xp->p)
{
int l = xp->data - 65;
if(!(--indegree[l])) s.push(l);
}
}
if(count < n) return 0;
else return 1;
}
int main()
{
int m;
char a[5];
while(scanf("%d", &m)!=EOF)
{
init();
memset(indegree, 0, sizeof(indegree));
memset(visit, 0, sizeof(visit));
int num = 0;
while(m--)
{
scanf("%s", a);
if(!visit[a[0]-65])
{
visit[a[0]-65] = 1;
num++;
}
if(!visit[a[2]-65])
{
visit[a[2]-65] = 1;
num++;
}
if(a[1]=='<')
{
list *q;
q = (struct node*)malloc(sizeof(node));
q->data = a[2];
q->p = zu[a[0]-65].p;
zu[a[0]-65].p = q;
indegree[a[2]-65]++;
}
else
{
list *q;
q = (struct node*)malloc(sizeof(node));
q->data = a[0];
q->p = zu[a[2]-65].p;
zu[a[2]-65].p = q;
indegree[a[0]-65]++;
}
}
if(topo(zu, num)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
原文地址:http://blog.csdn.net/u014355480/article/details/41962347