zoukankan      html  css  js  c++  java
  • AcWing848 有向图的拓扑序列

    给定一个n个点m条边的有向图,图中可能存在重边和自环。

    请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。

    若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

    输入格式
    第一行包含两个整数n和m

    接下来m行,每行包含两个整数x和y,表示存在一条从点x到点y的有向边(x, y)。

    输出格式
    共一行,如果存在拓扑序列,则输出拓扑序列。

    否则输出-1

    数据范围

    (1≤n,m≤105)

    输入样例

    3 3

    1 2

    2 3

    1 3

    输出样例

    1 2 3

    一道拓扑排序的模板题。拓扑排序的算法是,首先找到入度为0的点(所以需要一个数组to[]维护每个结点的入度),将它放入队列,然后依次枚举它的所有出边t->j,删掉它们之间的连接to[j]--,如果此时to[j]==0,那么将j入队,持续这个过程直到队列为空。

    代码:

    #include <iostream>
    #include <queue>
    #include <memory.h>
    using namespace std;
    const int N = 1e5+10;
    int h[N], e[N], ne[N], idx;
    int to[N], ans[N];
    int n, m;
    void add(int a, int b){
        e[idx] = b; ne[idx] = h[a]; h[a] = idx++;   //邻接表加入边的一般操作
    }
    
    bool toposort(){
        queue<int> q;
        int pp = 0;
        for(int i = 1; i <= n; ++i){     //首先找到入度为0的结点,将它加入队列和答案中
            if(to[i] == 0){
                q.push(i); 
                ans[pp++] = i;
                break;
                
            }
        }
        while(!q.empty()){
            int u = q.front(); q.pop();       //取出队首元素
            for(int i = h[u]; i != -1; i = ne[i]){  //对每个u的出边
                int v = e[i]; to[v]--;        //删掉u->v的连接
                if(to[v] == 0) {             //如果v的入度为0了,那么加入队列和答案中
                    ans[pp++] = v;
                    q.push(v);
                }
            }
        }
        return pp==n;
    }
    
    int main(){
        scanf("%d%d", &n, &m);
        memset(h, -1, sizeof(h));
        for(int i = 0; i < m; ++i){
            int a, b;
            scanf("%d%d", &a, &b);
            add(a, b);       //将a->b的边加入
            to[b]++;         //更新入度信息
        } 
        if(toposort()){      //如果有拓扑序,打印出结果
            for(int i = 0; i < n; ++i) printf("%d ", ans[i]);
        }else 
            printf("-1");
    }
    
  • 相关阅读:
    面试题15:链表中倒数第K个结点
    面试题31:连续子数组的最大和
    数据库索引实例
    面试题27:二叉搜索树与双向链表
    面试题28:字符串的排列
    java比较器Comparable接口和Comaprator接口
    面向对象知识汇总
    虚函数与纯虚函数
    Linux IO实时监控iostat命令详解
    hive GroupBy操作(翻译自Hive wiki)
  • 原文地址:https://www.cnblogs.com/patrolli/p/11802221.html
Copyright © 2011-2022 走看看