当我们知道一组大小关系之后,可判断所有关系是否都能成立,即关系间没有矛盾。
例如: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