HDU 3342 Legal or Not (拓扑排序)

本文介绍了一种算法,用于判断ACM-DIY群内成员之间的学习关系是否合法。通过构建图模型并运用拓扑排序检查环路,确保学习链条不存在循环依赖。

原题传送门


题面:

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值