图论-拓扑排序(21.8.19)

概念:

设A有最高优先级,BC优先级相等,D是最低优先级,表示为A->(B,C)->D,ABCD或ACBD这一序列就是就是拓扑序列。

在一个有向图中找一个拓扑序列的过程称为拓扑排序。

这个图必须是有向无环图(DAG)(DAG 就是一个从任何节点出发,只要按照指针方向走,无论选择哪种路径都不能回到起点的图)

基本思想:

请添加图片描述

1)从有向图中选一个无前驱(入度为0)的顶点 输出;
2)将此顶点和以它为起点的弧删除;
3)重复前两步,直到不存在无前驱的顶点;
4)若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序为一个拓扑序列;

算法步骤:

1、求所有顶点的入度,和它下一节点的出度,可以设两个数组;
2、把所有入度为0的顶点入队列或栈(注意是所有);
3、当栈或队列不为空

  1. 出栈或队列顶点为u,输出顶点u,然后开始处理它的下一级邻居;
  2. 顶点u的所有邻接点入度减一,如果有入度为0的顶点,则入栈或队列;
    4、最后停止的时候,可以根据出度为0的(既最后一个点)进行其他操作
    例如,总路径的条数种类
    5、若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序为一个拓扑序列;

其实用拓扑排序的很大一个原因就是 它原本就是有向无环图
注意队列的先进先出,所以等级高的一定先被处理了

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <queue>
#include <list>

using namespace std;
typedef long long ull;
const int N=1000001;
int ans;
ull n,k,x,y,m,sum=0;
int a,b;
int in[N],out[N];
queue<int>q;
vector<int>e[500005];//可理解为二维

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        e[i].clear();//初始化
    }

    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        e[a].push_back(b);//把相应值存储到结点a邻接表中
        out[a]++;//上级的出
        in[b]++;//下级的入
    }

    for(int i=1;i<=n;i++)//找寻最开头的点
    {
        if(in[i]==0) 
        {
            num[i] =1;
            q.push(i);
        }
    }

    while(!q.empty())
    {
        int head = q.front();//队首
        q.pop();
        int len = e[head].size();//邻居有多少
        for(int i=0;i<len;i++) //把他的所有邻居都处理了
        {
            int x = e[head][i];//当前点
            in[x]--;//入度
            if(in[x]==0) q.push(e[head][i]);
        }
    }
    for(int i=1;i<=n;i++)//找到最末端的点
    {
        if(out[i]==0) //相关操作
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值