拓扑排序

26 篇文章 1 订阅
1 篇文章 0 订阅
拓扑排序:在图论中,由一个有向非循环图(DAG)的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(Topological sorting)。
1.每个顶点出现且只出现一次;
2.若A在序列中排在B的前面,则在图中不存在从B到A的路径。

也可以定义为:拓扑排序是对有向无圈图的顶点的一种排序,它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面。


实现过程:

1.读入图,建一个记录顶点入度的数组,记录每个顶点的入度
2.建一个队列,记录入度为0的顶点
3.从队列中出来一个顶点u,遍历所有顶点,若u,v有边相连,则将所连的边标记为已删除(即令g[u][v]=0),
并对顶点v的入度减1,若顶点v的入度为0,入队;

4.若队空则退出,否则重复步骤4;


完成上述过程后,若所有顶点的度都为0,则说明该图是一个有向无回路图,否则为有回路

HDU 3342(Legal or Not)

题意:有n个人,m个关系,若A是B的师父,而B又是A的师父则说明这种关系不合法,判断这n个人中的关系合不合法;
思路:只需判断有无回路;
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;

const int SIZE = 200;
int g[SIZE][SIZE], de[SIZE];

int TopoSort(int n){
    queue<int> p;
    for(int i = 0;i < n;i++)
        if(de[i] == 0)
            p.push(i);            
    while(!p.empty()){
        int r = p.front();
        p.pop();
        for(int i = 0;i < n;i++)
            if(g[r][i]){
                de[i]--;
                g[r][i] = 0;
                if(!de[i])
                    p.push(i);
            }
    }
    for(int i = 0;i < n;i++)
        if(de[i] > 0)
            return 0;
     return 1;
}

int main(){
    int n, m;
    while(scanf("%d%d", &n, &m)){
        int i, j, a, b;
        memset(de, 0, sizeof(de));
        memset(g, 0, sizeof(g));
        if(n == 0&&m == 0)
            break;
        for(i = 0;i < m;i++){
            scanf("%d%d", &a, &b);
            if(g[b][a] == 1)
                continue;
            g[b][a] = 1;
            de[a]++;
        }
        if(TopoSort(n))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值