拓扑排序问题

拓扑排序是为了解决活动的先后问题,在满足拓扑排序的图中,任意一对结点<u,v>,总可以找到它们的顺序关系,例如u在v前,可能是直接,也可能是间接,思想就是建立一个有向无环图DAG,这样就可以满足结点的关系只有一种。

题目:若A是B的老师,则B是A的学生,但是不能出现环,即A是B的老师,B是C的老师,C又是A的老师;甚至A和B互为老师也是不允许的。要求给出N个人,M个关系<x,y>表示x是y的老师,而y是x的学生,判断是否为有向无环图。

思想是首先初始化各结点,按照输入的边,确定各结点的入度,当一个结点的入度为0时加入队列,每次从队列队首出队一个元素,将该结点所指向的结点的入度减1,若有结点因此入度减为0,则加入队列,直到所有的结点都经过队列弹出,即为有向无环图,否则不是有向无环图。

代码为:

#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#define N 1001
using namespace std;

vector<int> edge[N];
queue<int> Q;
int inDegree[N];

int main()
{
    int n,m;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        if(n == 0 && m == 0)
            break;
        for(int i = 0; i < n; i++)//编号从0开始
        {
            inDegree[i] = 0;
            edge[i].clear();
        }
        while(!Q.empty())
            Q.pop();
        while(m-- != 0)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            edge[a].push_back(b);
            inDegree[b]++;
        }
        for(int i = 0; i < n; i++)
        {
            if(inDegree[i] == 0)
            {
                Q.push(i);
            }
        }
        int cnt = 0;//记录已经加入到拓扑序列的结点
        while(!Q.empty())
        {
            int nowP = Q.front();
            Q.pop();
            cnt++;//每次出队一个元素,拓扑网络中的结点数就加1
            for(int i = 0; i < edge[nowP].size(); i++)
            {
                inDegree[edge[nowP][i]]--;//vector中的元素下标从0开始
                if(inDegree[edge[nowP][i]] == 0)
                {
                    Q.push(edge[nowP][i]);
                }
            }
        }
        if(cnt == n)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值