zoukankan      html  css  js  c++  java
  • 拓扑排序

    前几个星期落下的终于要开始一一补上啦~~这个寒假坚持把这本书看完!

    机考最后一道题就这么简单,无语,早知道先做这道好了。最简单的拓扑排序应用,判断一个有向图是不是无环的。

    标准的拓扑排序代码,《图论与应用》里代码风格不是很喜欢,所以还是觉得这个比较好看一点。

    View Code
    /*
      (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
      (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
      (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.
    */
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    #define Max 100
    int ans[Max];
    //可以完成拓扑排序则返回True,否则返回false 
    bool TopologicalSort(int map[][Max], int n)  //a为邻接矩阵, n为顶点个数 
    {
        int into[Max];
        memset(into, 0, sizeof(into));
        memset(ans, 0, sizeof(ans));
    
        //计算入度 
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if (map[i][j] > 0)
                    into[j]++;
            }
        }
    
        for (int i = 1; i <= n; i++)
        { 
            int j = 1;
    
        //寻找入度为0的点,找不到说明拓扑不可能完成 
            while (into[j] != 0)
            {
                j++;
                if (j > n)
                    return false;
            }
    
        //ans依次记录入度为1的点 
            ans[i] = j;
        //删除入度为0的点 
            into[j] = -1;
    
        //并且删去从该顶点发出的全部有向边. 
            for (int k = 1; k <= n; k++)
            {
                if (map[j][k] > 0)
                    into[k]--;
            }
        }
        //输出拓扑排序的情况 
        for (int i = 1; i <= n; i++)
        {
            cout << ans[i] << " ";
        }
    
        cout << endl;
    
        return true;
    }

    题目可以见 http://soj.me/show_problem.php?pid=1001&cid=794

    View Code
    /*
      (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
      (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
      (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.
    
        ps.最简单的拓扑排序应用,判断有环或无环 http://soj.me/show_problem.php?pid=1001&cid=794
    */
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    #define Max 100
    int ans[Max];
    //可以完成拓扑排序则返回True,否则返回false 
    bool TopologicalSort(int map[][Max], int n)  //a为邻接矩阵, n为顶点个数 
    {
        int into[Max];
        memset(into, 0, sizeof(into));
        memset(ans, 0, sizeof(ans));
    
        //计算入度 
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                if (map[i][j] > 0)
                    into[j]++;
            }
        }
    
        for (int i = 1; i <= n; i++)
        { 
            int j = 1;
    
        //寻找入度为0的点,找不到说明拓扑不可能完成 
            while (into[j] != 0)
            {
                j++;
                if (j > n)
                    return false;
            }
    
        //ans依次记录入度为0的点 
            ans[i] = j;
        //删除入度为0的点 
            into[j] = -1;
    
        //并且删去从该顶点发出的全部有向边. 
            for (int k = 1; k <= n; k++)
            {
                if (map[j][k] > 0)
                    into[k]--;
            }
        }
        //输出拓扑排序的情况 
        for (int i = 1; i <= n; i++)
        {
            cout << ans[i] << " ";
        }
    
        cout << endl;
    
        return true;
    }
  • 相关阅读:
    浅析Android中的消息机制
    Delphi 调用webservice接口
    进程间的相互调用与参数传递【Delphi版】
    网络上可供测试的Web Service
    mysql复制功能——“masterslave”结构
    SQL Server 2008 事件探查器【转】
    mysql常用存储引擎对比(转)
    线程池基本理论
    中国金融体系简略图
    《Windows核心编程》学习笔记(6)– 线程的创建、与进程的关系、伪句柄转换
  • 原文地址:https://www.cnblogs.com/chenyg32/p/2869641.html
Copyright © 2011-2022 走看看