1.2 排序原理
從圖中選擇乙個入度為0的頂點,輸出該頂點;
從圖中刪除該頂點及所有與該頂點相連的邊
重複上述兩步,直至所有頂點輸出。
或者當前圖中不存在入度為0的頂點為止。此時可說明圖中有環。因此,也可以通過拓撲排序來判斷乙個圖是否有環。
1.3過程示例
如果我們有如下的乙個有向無環圖,我們需要對這個圖的頂點進行拓撲排序,過程如下:
首先,我們發現v6和v1是沒有前驅的,所以我們就隨機選
去乙個輸出,我們先輸出v6,刪除和v6有關的邊,得到如
下圖結果:
然後,我們繼續尋找沒有前驅的頂點,發現v1沒有前驅,
所以輸出v1,刪除和v1有關的邊,得到下圖的結果:
然後,我們又發現v4和v3都是沒有前驅的,那麼我們就隨
機選取乙個頂點輸出(具體看你實現的演算法和圖儲存結構),
我們輸出v4,得到如下圖結果:
然後,我們輸出沒有前驅的頂點v3,得到如下結果:
此時我們發現剩下的v2和v5入度均為0,然後輸出v2和v5
可得到該圖的拓撲排序為:v6 v1 v4 v3 v2 v5
1.4思路
建立乙個二維陣列來表示鄰接矩陣,乙個一維陣列記錄各點的入度
依次輸入一對相連的點,存入陣列,並用1來標記這兩個點相連。
一維陣列記錄的第二個點的入度數+1
1.5 kahn演算法的描述
每一次,選乙個入度為0 的頂點輸出,然後將其所有後繼頂點的入度-1(即把這個頂點往外伸展的邊刪除),重複這
兩步直至輸出所有頂點,或找不到入度為0 的頂點為止(這就是有「環」的情況)
#include const int maxn=1e3+10;
int p[maxn][maxn],vis[maxn];//p記錄兩點是否相連,vis記錄點的入度
int n,m;
int flag[maxn][maxn];
void toposort()
break;
}} }
}int main()
} toposort();//拓撲排序
} return 0;
}
練習題
hdu 1285 確定比賽名次
1285題解
poj 2367genealogical tree
2367題解
uva 10305 ordering tasks 水題,沒有題解
hdu 2094
poj 2585
hdu 3342
hdu 2647
2.1定義:樹中距離最大的兩個結點之間的距離稱為樹的直徑。
2.2求法:兩次dfs或bfs。第一次任意選乙個點a進行dfs(bfs)找到離它最遠的
點b,此點b就是最長路的乙個端點,再以b點進行dfs(bfs),找到
離它最遠的點c,點c就是最長路的另乙個端點,於是就找到了樹
的直徑。
# include # include # include # include const int maxn =100020;
using namespace std;
int dis[ maxn ],ans;
bool vis[ maxn ];
vector > v[ maxn ];//宣告不定長陣列vector,存邊的關係
int bfs(int x)
pair t;
for (int i=0;i>x>>y>>z)
ans =0;
int point =bfs (1);//第一次bfs找直徑的乙個端點 point
ans =0;
bfs( point );//第二次,對point用bfs,確定樹的直徑
cout 練習題:
poj 2631:roads in the north
2631題解
poj 1985 cow marathon
1985題解
poj 1383 labyrinth
家譜樹(拓撲排序)
有個人的家族很大,輩分關係很混亂,請你幫整理一下這種關係。給出每個人的孩子的資訊。輸出乙個序列,使得每個人的後輩都比那個人後列出。第1行乙個整數n 1 n 100 表示家族的人數 接下來n行,第i行描述第i個人的兒子 每行最後是0表示描述完畢。輸出乙個序列,使得每個人的後輩都比那個人後列出 如果有多...
知識點 8 4 拓撲排序與關鍵路徑
總目錄 8 圖論 8.4 拓撲排序與關鍵路徑 前言 想起當年參加 ctsc 時 dp 王 zed 用拓撲序 dp 過了一道題直接一飛沖天,而一旁的蒟蒻拿了個 10 分 gg。子目錄列表 1 dag 與 aov 網 2 拓撲排序 3 aoe 網與關鍵路徑 8.4 拓撲排序與關鍵路徑 1 dag 與 a...
SDOI2013 直徑(樹的直徑)
小q最近學習了一些圖論知識。根據課本,有如下定義。樹 無迴路且連通的無向圖,每條邊都有正整數的權值來表示其長度。如果一棵樹有n個節點,可以證明其有且僅有n 1 條邊。路徑 一棵樹上,任意兩個節點之間最多有一條簡單路徑。我們用 dis a,b 表示點a和點b的路徑上各邊長度之和。稱dis a,b 為a...