Legal or Not
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5928 Accepted Submission(s): 2748
Problem Description
ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that just like a big family. Every day,many “holy cows” like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas. When someone has questions, many warm-hearted cows like Lost will come to help. Then the one being helped will call Lost “master”, and Lost will have a nice “prentice”. By and by, there are many pairs of “master and prentice”. But then problem occurs: there are too many masters and too many prentices, how can we know whether it is legal or not?
We all know a master can have many prentices and a prentice may have a lot of masters too, it’s legal. Nevertheless,some cows are not so honest, they hold illegal relationship. Take HH and 3xian for instant, HH is 3xian’s master and, at the same time, 3xian is HH’s master,which is quite illegal! To avoid this,please help us to judge whether their relationship is legal or not.
Please note that the “master and prentice” relation is transitive. It means that if A is B’s master ans B is C’s master, then A is C’s master.
Input
The input consists of several test cases. For each case, the first line contains two integers, N (members to be tested) and M (relationships to be tested)(2 <= N, M <= 100). Then M lines follow, each contains a pair of (x, y) which means x is y’s master and y is x’s prentice. The input is terminated by N = 0.
TO MAKE IT SIMPLE, we give every one a number (0, 1, 2,…, N-1). We use their numbers instead of their names.
Output
For each test case, print in one line the judgement of the messy relationship.
If it is legal, output “YES”, otherwise “NO”.
Sample Input
3 2 0 1 1 2 2 2 0 1 1 0 0 0
Sample Output
YES NO
题意:给出一个关系(x,y)如果x是y的师傅,并且y是x的师傅,出现这种长辈不分的情况就要输出no,正常的化就输出yes;
思路:基本都能看出来,这个就是topo判断成环问题,如何判断成环呢,就运用队列,能成环的元素都无法进队列,不能成环的都可以进队列,最后看进入队列的有多少人 如果是总人数,那就是正常,不然就是no.
ac代码:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int map[101][101],inde[101];
int n,m;
void topo(){
queue<int>q;
int ans=0,i,k;
for(i=0;i<n;i++)//最开始的进入队列,如果没有构成环的话,那么至少有意的元素的度是0,至少有一个元素能进队列。
if(!inde[i]){
q.push(i);
ans++;
}
while(!q.empty()){//当有元素能进入队列时,在逐步进行分析。
k=q.front();
q.pop();
for(i=0;i<n;i++)
if(map[k][i]){//找到和这个元素相关的元素,减少他的度数,如果能变为0,就让他入队列。
inde[i]--;
if(!inde[i]){
q.push(i);
ans++;
}
}
}//通过这个while循环使得所有不能构成环的元素都进入了队列,那么比较一下如果所有元素都进入队列了,那么就是对的。
if(ans==n)
printf("YES\n");
else
printf("NO\n");
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
int i;
memset(map,0,sizeof(map));
memset(inde,0,sizeof(inde));
for(i=0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
if(!map[a][b]){
map[a][b]=1;
inde[b]++;
}
} //这之前都是关系的输入工作。
topo();
}
return 0;
}