Queue 应用——拓扑排序

1. 拓扑排序

题目描述:对一个有向无环图(Directed Acyclic Graph, DAG)G进行拓扑排序,是将G中所有顶点排成线性序列,是的图中任意一堆顶点u和v,若边(u, v)在E(G)中,则u在线性序列中出现在v之前。

如:

分析:

1)首先我们要将图G存入一个邻接矩阵中,保存该图;

2)计算每个顶点的入度,存储一个以为数组中;

3)从有向图中选择一个没有前驱(即入度为0)的节点并输出;

4)从图中删除该节点,并且删除从该节点发出的全部又想边;

5)重复上面两个步骤,直至剩余的图中不再存在没有前驱的节点为止。

进一步思考:

1)拓扑排序的本质是不断输出入度为0的点,这种方法可以用于判断图中是否有环;

2)拓扑排序其实给出的是节点之间的偏序关系;

Answer:

class TopologySort {
    private int[][] aja = {{0,1,0,0,0,1,1,0,0,0,0,0,0},
                 {0,0,0,0,0,0,0,0,0,0,0,0,0},
              {1,0,0,1,0,0,0,0,0,0,0,0,0},
              {0,0,0,0,0,1,0,0,0,0,0,0,0},
              {0,0,0,0,0,0,0,0,0,0,0,0,0},
              {0,0,0,0,1,0,0,0,0,0,0,0,0},
              {0,0,0,0,1,0,0,0,0,1,0,0,0},
              {0,0,0,0,0,0,1,0,0,0,0,0,0},
              {0,0,0,0,0,0,0,1,0,0,0,0,0},
              {0,0,0,0,0,0,0,0,0,0,1,1,1},
              {0,0,0,0,0,0,0,0,0,0,0,0,0},
              {0,0,0,0,0,0,0,0,0,0,0,0,1},
              {0,0,0,0,0,0,0,0,0,0,0,0,0}};

    public int[][] getEdge() {
        return aja;
    }

    /**
     * 该函数根据邻接矩阵计算每个节点的入度
     * @param edge
     * @return
     */
    public int[] getInDegree(int[][] edge) {
        int len = edge.length;
        int[] inDegree = new int[len];
        for(int j=0; j<len; j++) {
            int count = 0;
            for(int i=0; i<len; i++)
                if(edge[i][j] == 1)
                    count++;
            inDegree[j] = count;
        }
        return inDegree;
    }

    public List<Integer> topoSort(int[][] edge) {
        List<Integer> res = new ArrayList<Integer>();
        int len = edge.length;
        int[] inDegree = getInDegree(edge);

        Queue<Integer> q = new LinkedList<Integer>();
        //将入度为0的节点压入队列中
        for(int i=0; i<inDegree.length; i++)
            if(inDegree[i] == 0) {
                q.add(i);
                res.add(i);
            }

        //对于队列中的元素(入度为0的元素)
        while(!q.isEmpty()) {
            int element = q.remove();
            for(int j=0; j<len; j++) {
                if(edge[element][j] == 1)  {
                    inDegree[j]--;
                    if(inDegree[j] == 0) {
                        q.add(j);
                        res.add(j);
                    }
                }
            }
        }
        return res;
    }
}
时间: 2024-11-05 15:54:09

Queue 应用——拓扑排序的相关文章

hdu1811 Rank of Tetris 并查集+拓扑排序

1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 struct node//边 7 { 8 int a, b;//顶点 9 char ch;//运算符 10 }c[10005]; 11 vector<int>map[10005];//map数组存贮邻接表 (大佬都是这么开数组的) 12

两道拓扑排序的问题

多久没写东西了啊.... 两道拓扑排序Liv.1的题....方法是一样的~~ <拓扑排序·二> 题目:http://hihocoder.com/contest/hiho81/problem/1 一个电脑网路,单向边,如果存在边u->v,那么u的病毒会感染到v. 要点,不存在环!那么如果u的入度=0的话,那么u中的病毒数不会再变化. 想到拓扑排序.不断删去入度为0的点.每次删去节点u,如果存在u->v,那么病毒数 num[v] += num[u].问题解决. (用queue实现拓扑排

拓扑排序介绍

拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑排序,它就是用来确定事物发生的顺序的. 在拓扑排序中,如果存在一条从顶点A到顶点B的路径,那么在排序结果中B

hdu1811 Rank of Tetris(拓扑排序+并查集)

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6920    Accepted Submission(s): 1947 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

转:【拓扑排序详解】+【模板】

转自:http://www.cnblogs.com/skywang12345/p/3711489.html 拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

hdu1285(拓扑排序)

这道题要求没有输赢关系的两个元素必须按照升序输出,有输赢关系的,赢得在输的前面,所以用队列或者栈来降低时间复杂度的优化过的拓扑排序会出错. 比如这组输入 5 3 1 2 2 3 4 5 至少我写的两种拓扑排序都wa了.但是不用队列或者栈来优化的话, 1.每次都从头至尾扫描一遍,找到一个没标记过的节点, 2.将它标记 3.然后删除从它出来的每条边. 重复这三个操作,加标记的次序,就是题目要的答案. 下面的代码中用到了队列,但只是用来保存答案而已.并没有用它优化的意思. #include <iost

POJ1420 Spreadsheet(拓扑排序)注意的是超内存

Spreadsheet Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 617   Accepted: 290 Description In 1979, Dan Bricklin and Bob Frankston wrote VisiCalc, the first spreadsheet application. It became a huge success and, at that time, was the ki