拓撲排序講解

来源:http://www.cnblogs.com/z360/archive/2017/05/22/6891705.html
-Advertisement-
Play Games

在這裡我們要說的拓撲排序是有前提的 我們在這裡說的拓撲排序是基於有向無環圖的!!!。 (⊙o⊙)…我所說的有向無環圖都知道是什麼東西吧。。 如果不知道,我們下麵先來來說說什麼是有向無環圖。 所謂有向無環圖,顧名思義是不存在環的有向圖(至於有向圖是什麼不知道的在前面我們有一個圖論講解上都有)。 點的入 ...


在這裡我們要說的拓撲排序是有前提的

        我們在這裡說的拓撲排序是基於有向無環圖的!!!。

(⊙o⊙)…我所說的有向無環圖都知道是什麼東西吧。。

如果不知道,我們下麵先來來說說什麼是有向無環圖。

所謂有向無環圖,顧名思義是不存在環的有向圖(至於有向圖是什麼不知道的在前面我們有一個圖論講解上都有)。

點的入度:以這個點為結束點的邊數。

點的出度:以這個點為出發點的邊的條數。

拓撲序就是對於一個節點的一個排列,使得(u,v)屬於E,那麼u一定出現在v的前面。然而拓撲排序就是一個用來求拓撲序的東西。

對於左面的這個圖,一個合法的拓撲序是(1,2,4,3,5)。

 

又有一個問題了,知道了這些東西後,我們又要怎樣求一個有向無環圖的拓撲序呢?

我們可以觀察到拓撲排序的定義是:若(u,v)∈E,那麼u在排列中出現的位置一定在v前面。

也就是說,考慮一個節點u,當我們刪除u在序列中處於他前面的所有點之後,u的入度應該是0.

因此,我們就得到了一個拓撲排序的大致的演算法思路。

具體怎麼著呢  ?。?

迴圈n次

    選定一個入度為0且仍存在(未出現在序列中)的點v

  刪除點v以及從從點v出發的所有邊,更新剩餘點的入度

重覆上述過程,這樣我們就可以得到一個合法的拓撲序。

既然這樣,我們就總結下拓撲排序的精髓吧。

精髓(具體方法):
⑴ 從圖中選擇一個入度為0的點加入拓撲序列。
⑵ 從圖中刪除該結點以及它的所有出邊(即與之相鄰點入度減1)。
反覆執行這兩個步驟,直到所有結點都已經進入拓撲序列。

還可不可以消化得了?

如果還不可以的話,下麵我們就來具體講一講拓撲排序吧。

參考博客:http://blog.csdn.net/dm_vincent/article/details/7714519

一。定義

將有向圖中的頂點以線性方式進行排序。即對於任何連接自頂點u到頂點v的有向邊uv,在最後的排序結果中,頂點u總是在頂點v的前面。

 

如果這個概念還略顯抽象的話,那麼不妨考慮一個非常非常經典的例子——選課。我想任何看過數據結構相關書籍的同學都知道它吧。假設我非常想學習一門機器學習的課程,但是在修這麼課程之前,我們必須要學習一些基礎課程,比如電腦科學概論,C語言程式設計,數據結構,演算法等等。那麼這個制定選修課程順序的過程,實際上就是一個拓撲排序的過程,每門課程相當於有向圖中的一個頂點,而連接頂點之間的有向邊就是課程學習的先後關係。只不過這個過程不是那麼複雜,從而很自然的在我們的大腦中完成了。將這個過程以演算法的形式描述出來的結果,就是拓撲排序。

二。代碼實現

#include <bits/stdc++.h>
using namespace std;

const int maxn=100000+15;
struct Edge
{
    int x,y,next;
    Edge(int x=0,int y=0,int next=0):
    x(x),y(y),next(next) {}
}edge[maxn];
int n,m,head[maxn],sumedge,inn[maxn];
int ins(int x,int y)
{
    edge[++sumedge]=Edge(x,y,head[x]);
    return head[x]=sumedge;
}
int Head,tail,que[maxn];
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        ins(x,y);
        inn[y]++;
    }
    Head=1;tail=0;
    for (int i=1;i<=n;i++)
     if (inn[i]==0) que[++tail]=i;//如果該點的入度為0,刪掉與這個點相連的點,刪後如果入度為0的話,把該點入隊 .
    for (;Head<=tail;Head++)//迴圈枚舉與該點相連的點,把該點入隊。 
    {//迴圈上述過程,直到說有的點都入隊(有向無環圖,每一個點肯定都與一個點相連,這樣我們重覆這個過程,就可以很好地把所有的帶點都考慮到,如此一來,所有的點就都入隊了。 
        int x=que[Head];
        for (int u=head[x];u;u=edge[u].next)
        {
            inn[edge[u].y]--;//刪掉與這個點相連的點
            if (inn[edge[u].y]==0)// 刪後如果入度為0的話
             que[++tail]=edge[u].y;//把該點入隊 
        }
    }
    return 0;
}

就說這些吧,我們在下麵還會再說幾個例題。(那就請看下一頁吧)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一般我們常見的RPC框架都包含如下三個部分: 註冊中心,用於服務端註冊遠程服務以及客戶端發現服務 服務端,對外提供後臺服務,將自己的服務信息註冊到註冊中心 客戶端,從註冊中心獲取遠程服務的註冊信息,然後進行遠程過程調用 上面提到的註冊中心其實屬於服務治理,即使沒有註冊中心,RPC的功能也是完整的。之 ...
  • 1. 攔截器用途 (1)攔截未登錄用戶直接訪問某些鏈接 (2)攔截日誌信息 (3)攔截非法攻擊,比如sql註入 2. 涉及jar、類 (1)spring-webmvc.jar (2)HandlerInterceptor(org.springframework.web.servlet:介面)、 Asy ...
  • 上周在安裝搜索引擎Elasticsearch時,要求安裝比較新的java 版本,我選擇了java 1.8.0,安裝java 成功後使用java -version 發現使用的版本仍舊是1.6.0, 查詢了一些資料,發現可以使用Linux的alternatives命令替換選擇軟體的版本。 說明:alte ...
  • 伺服器端多線程類: ...
  • dplyr專註處理dataframe對象, 並提供更穩健的與其它資料庫對象間的介面。 一、5個關鍵的數據處理函數: select() 返回列的子集 filter() 返回行的子集 arrange() 根據一個或多個變數對行排序。 mutate() 使用已有數據創建新的列 summarise() 對各 ...
  • querySet.distinct() 去重覆__exact 精確等於 like 'aaa' __iexact 精確等於 忽略大小寫 ilike 'aaa' __contains 包含 like '%aaa%' __icontains 包含 忽略大小寫 ilike '%aaa%',但是對於sqlit ...
  • Given a list, rotate the list to the right by k places, where k is non-negative. ...
  • 一:參考官方文檔 1. Elasticsearch 5.4.0英文手冊 https://www.elastic.co/guide/en/elasticsearch/reference/5.4/search-request-post-filter.html 2. 《Elasticsearch權威指南》 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...