基础拓扑排序

前言

拓扑排序是一种针对“有向无环图”的算法,用于解决一些有“依赖关系”的问题。

拓扑排序保证了当处理到某个电时,其所有的如电都已经处理过了。

例如右边这个图,拓扑序可以保证处理点2之前,点4和点6都处理过了、处理点3之前,点2和点6都处理过。

 拓扑排序不一定是“唯一”的,只要满足拓扑关系即可

以下是一些上图中的可能拓扑序:

[1,4,6,5,7,3]

[7,1,4,6,2,3,5]

[7,1,6,4,2,5,3]

,,,,

我们可以发现每个点的左侧包含它的所有入点

拓扑排序一般借助queue(队列),使用类似BFS实现

先处理出每个点的入度,这个在读入边的时候处理。图一般用邻接表建立

for(int i=0;i<m;i++){
    int x=scan.nextInt();
    int y=scan.nextInt();
    list[x].add(y);
    f[y]++;
}
Queue<Integer> q=new LinkedList<>();
for(int i=1;i<=n;i++){
    if(f[i]==0){//入度为0直接加入队列
       q.add(i);
    }
}
while(!q.isEmpty()){
    int x=q.poll();
    for(int y:list[x]){
        if(f[y]==0)//判断Y是否入度为零,为零表示Y的入点已经处理完成了,Y可以入队
            q.add(y);    
    }
}

拓扑和动态规划的结合

在枚举X->Y的时候,可以进行状态转移,于是可以和动态规划结合起来。这样的DP也叫做DAG-DP(有向无环图上的动态规划)

状态转移一般只发生在枚举所有边的时候。

Queue<Integer> q=new LinkedList<>();
for(int i=1;i<=n;i++){
    if(f[i]==0)
        q.add(i);
}
while(!q.isEmpty()){
//进行dp转移
    int x=q.poll();
    for(int y:list[x]){
        f[y]--;//处理之后判断Y的入度是否为零
        if(f[y]==0)
            q.add(y);
    }
}

例题

给定一个n个点,m条边的有向无环图,小明从入度为0点出发,顺着边最远能走多远,若不存在这样的点,输出0

输入描述

第一行输入一个n,m

接下来m行,每行输入两个整数u,v代表有一条有向边从u到v

输出描述

输出一个整数 表示最长距离

输入输出样例

示例

输入

2 1

1 2

输出

1

(答案后期更新)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值