拓扑排序
题目1448:Legal or Not
题目描述:
-
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.
输入:
-
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.
输出:
-
For each test case, print in one line the judgement of the messy relationship.If it is legal, output "YES", otherwise "NO".
样例输入:
-
3 2
0 1
1 2
2 2
0 1
1 0
0 0
样例输出:
-
YES
NO
代码如下:
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
#define N 101
vector<int> edge[N];
queue<int> q;
int main()
{
int n, m;
int inDegree[N]; // 统计每个结点的入度
while (scanf("%d", &n) != EOF)
{
if (n == 0) break;
scanf("%d", &m);
for (int i = 0; i < n; i++)
{
inDegree[i] = 0;
edge[i].clear();
}
while (!q.empty()) q.pop();
while (m--)
{
int a, b;
scanf("%d%d", &a, &b);
inDegree[b]++; // //又出现了一条弧头指向b的边,累加结点b的入度
edge[a].push_back(b);
}
for (int i = 0; i < n; i++)
if (0 == inDegree[i]) q.push(i); // 入度为0的结点入队
int cnt = 0;
while (!q.empty())
{
int nowP = q.front();
q.pop();
cnt++;
for (int i = 0; i < edge[nowP].size(); i++)
if (0 == --inDegree[edge[nowP][i]]) q.push(edge[nowP][i]);
}
puts(cnt == n ? "YES" : "NO");
}
return 0;
}