题面:
Legal or Not
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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 and 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
题面描述
ACM-DIY是一个很大的QQ群,里面也有很多大佬.大佬们都是相互学习的.因为相互学习的原因,会出现A向B学习,B向C学习,C向A学习的情况.现在给出大佬们的学习关系.若出现了学习链循环的时候则不能认为他们组成了legal.求解是否完全为legal.
题目分析
检查环.将大佬们视为节点,学习关系视为单向路.则这些节点和路形成了一张图,若图中出现了环则不能称为legal,若没出现则能称为legal.可以用拓扑排序的方法来检查是否有环.
具体过程:将单向路都记录下来,同时记录每个点的入度,找出入度为0的点,加入队列.将该点通向的点的入度-1,并将其中入度为0的点都加入队列,直到队列为空,此时若是无环存在,则全部点的入度都为0,若存在入度不为0的点则说明图内存在环.
具体代码
#include <iostream>
#include <iomanip>
#include <string.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
const int maxn = 1e5;
const int inf = 0x3f3f3f;
typedef long long int ll;
typedef pair < int , int > pii;
vector < int > rel[105];//记录该点能到达的点
int in[105];//统计入度
int N , M;
bool check()
{
int cnt = 0;
queue < int > q;
for(int i = 0; i < N; i++)
{
if(!in[i])//入度为0
{
q.push(i);
}
}
while(!q.empty())
{
int i = q.front();
q.pop();
for(int j = 0; j < rel[i].size(); j++)
{
in[rel[i][j]]--;//删边已减少入度
if(!in[rel[i][j]])//若入度为0则加入队列
{
q.push(rel[i][j]);
}
}
}
for(int i = 0; i < N; i++)
{
if(in[i])//入度不为0
{
return false;
}
}
return true;
}
int main()
{
while(cin >> N >> M , N && M)
{
for(int i = 0; i < N; i++)
{
rel[i].clear();
}
memset(in , 0 , sizeof(in));
for(int i = 1; i <= M; i++)
{
int sta , fin;
cin >> sta >> fin;
in[fin]++;
rel[sta].push_back(fin);
}
if(check())
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
return 0;
}