[JLU] 資料結構與演算法上機題解思路分享-第三次上機

陆爻齐發表於2024-07-02

前言

首先,請務必自己盡全力嘗試實現題目,直接看成品程式碼,思維就被拘束了,也很容易被查重。

這裡只是思路解析的部落格,程式碼倉庫在 JLU_Data_Structures_Record

希望你能在這裡找到你想要的:)

正文

A 圖的建立

分數 10
作者 朱允剛
單位 吉林大學
請編寫程式建立一個有向圖。有向圖中包含n個頂點,編號為0至n-1。

輸入格式:
輸入第一行為兩個正整數n和e,分別表示圖的頂點數和邊數,其中n不超過20000,e不超過20000。接下來e行表示每條邊的資訊,每行為3個非負整數a、b、c,其中a和b表示該邊的端點編號,c表示權值。各邊並非按端點編號順序排列。

輸出格式:
按頂點編號遞增順序輸出每個頂點引出的邊,每個頂點佔一行,若某頂點沒有引出邊,則不輸出。每行表示一個頂點引出的所有邊,格式為a:(a,b,w)……,表示有向邊a->b的權值為w,a引出的多條邊按編號b的遞增序排列。

輸入樣例:
7 7
0 1 5
0 3 7
0 6 6
1 2 4
2 5 1
3 5 3
6 5 4

輸出樣例:
0:(0,1,5)(0,3,7)(0,6,6)
1:(1,2,4)
2:(2,5,1)
3:(3,5,3)
6:(6,5,4)

程式碼長度限制
16 KB
時間限制
500 ms
記憶體限制
20 MB


該題只是圖的建立,眾所周知,圖可以用鄰接矩陣或鄰接連結串列實現,這裡採用了鄰接連結串列,只要記錄邊和權值即可。


B 圖的刪邊操作

分數 10
作者 朱允剛
單位 吉林大學
請編寫程式對給定的有向圖刪除若干條邊。有向圖中包含n個頂點,編號為0至n-1。

輸入格式:
輸入第一行為兩個正整數n和e,分別表示圖的頂點數和邊數,其中n不超過20000,e不超過1000。接下來e行表示每條邊的資訊,每行為3個非負整數a、b、c,其中a和b表示該邊的端點編號,c表示權值。各邊並非按端點編號順序排列。隨後一行為一個整數k,表示刪除的邊的條數,接下來k行,每行為2個非負整數a、b,表示待刪除的邊為a->b。保證刪除的邊一定在原圖中。

輸出格式:
輸出執行刪邊操作之後的圖。每行表示一個頂點引出的所有邊,格式為a:(a,b,w)……,表示有向邊a->b的權值為w,a引出的多條邊按編號b的遞增序排列。若某頂點沒有引出邊,則不輸出。

輸入樣例:
7 7
0 1 5
0 3 7
0 6 6
1 2 4
2 5 1
3 5 3
6 5 4
2
2 5
0 1

輸出樣例:
0:(0,3,7)(0,6,6)
1:(1,2,4)
3:(3,5,3)
6:(6,5,4)

程式碼長度限制
16 KB
時間限制
200 ms
記憶體限制
64 MB


圖的建立同上圖,這裡的刪邊如果是鄰接連結串列注意要刪除時,確保不要一刪就刪了多個就行


C 圖深度優先遍歷

分數 10
作者 朱允剛
單位 吉林大學
編寫程式對給定的有向圖(不一定連通)進行深度優先遍歷,圖中包含n個頂點,編號為0至n-1。本題限定在深度優先遍歷過程中,如果同時出現多個待訪問的頂點,則優先選擇編號最小的一個進行訪問,以頂點0為遍歷起點。

輸入格式:
輸入第一行為兩個整數n和e,分別表示圖的頂點數和邊數,其中n不超過20000,e不超過50。接下來e行表示每條邊的資訊,每行為兩個整數a、b,表示該邊的端點編號,但各邊並非按端點編號順序排列。

輸出格式:
輸出為一行整數,每個整數後一個空格,即該有向圖的深度優先遍歷結點序列。

輸入樣例1:
3 3
0 1
1 2
0 2
輸出樣例1:
0 1 2
輸入樣例2:
4 4
0 2
0 1
1 2
3 0
輸出樣例2:
0 1 2 3
程式碼長度限制
16 KB
時間限制
50 ms
記憶體限制
64 MB


建立圖後,進行DFS就行了,沒啥講的

要不簡單講下DFS或BFS好了,就是從一個點入手,搜尋該點所連的所有點並加入陣列中,無論棧或佇列,記錄然後提出一點,繼續搜尋,加入記錄,往復至無點可尋。

嘛,突然想起,如果前這幾道題都用鄰接矩陣,或許實現就簡單很多了


D 單源最短路徑

分數 30
作者 朱允剛
單位 吉林大學
請編寫程式求給定正權有向圖的單源最短路徑長度。圖中包含n個頂點,編號為0至n-1,以頂點0作為源點。

輸入格式:
輸入第一行為兩個正整數n和e,分別表示圖的頂點數和邊數,其中n不超過20000,e不超過1000。接下來e行表示每條邊的資訊,每行為3個非負整數a、b、c,其中a和b表示該邊的端點編號,c表示權值。各邊並非按端點編號順序排列。

輸出格式:
輸出為一行整數,為按頂點編號順序排列的源點0到各頂點的最短路徑長度(不含源點到源點),每個整數後一個空格。如源點到某頂點無最短路徑,則不輸出該條路徑長度。

輸入樣例:
4 4
0 1 1
0 3 1
1 3 1
2 0 1
輸出樣例:
1 1
程式碼長度限制
16 KB
時間限制
100 ms
記憶體限制
20 MB


就是迪傑斯特拉演算法的使用,沒有什麼可以引申的


E 雙十一

分數 20
作者 朱允剛
單位 吉林大學
雙十一期間,某著名電商平臺“東東”為應對銷售高峰,準備在n個城市中再增加一個自營倉庫,其要求是該倉庫設在n個城市中的某個城市,且距離其他所有城市的最短距離之和最小。請編寫程式幫助“東東”找出設立倉庫的地點。假定n個城市編號為0至n-1,它們之間至少有一個城市與其他所有城市可及。

輸入格式:
輸入包含多組資料。每組資料第一行為兩個正整數n和e,均不超過100。n表示城市數。接下來e行表示兩個城市間的距離資訊,每行為3個非負整數a、b、c,其中a和b表示兩個城市編號,c表示城市間的距離。

提示:可使用EOF判斷輸入結束。

輸出格式:
輸出為一個整數,表示建立倉庫的城市編號,如多個城市滿足要求,則輸出編號最小者。

輸入樣例:
6 5
0 1 1
0 2 1
0 3 1
0 4 1
0 5 1
4 5
0 1 1
0 2 5
1 2 2
1 3 4
2 3 1

輸出樣例:
0
1

程式碼長度限制
16 KB
時間限制
50 ms
記憶體限制
64 MB


該題的本質是找到一個到其它點距離之和最小的點,理所當然地應該使用Prim演算法,求出各個點到其它所有點距離之和最短。


F 任務拓撲排序

分數 30
作者 朱允剛
單位 吉林大學
一個工程被分解成n個子任務,編號為0至n-1。要完成整個工程需要完成所有的子任務。其中一些子任務必須先於另外一些子任務被完成。給定各子任務之間的先後關係,請編寫程式給出一個合理的任務完成順序,若工程不可行,程式亦能識別。

輸入格式:
輸入第一行為兩個整數n和e,均不超過100。n表示子任務數。接下來e行,表示已知的兩個子任務間的先後關係,每行為兩個整數a和b,表示任務a必須先於任務b完成。

輸出格式:
若工程不可行(一些子任務以自己為先決條件),輸出“unworkable project”;若工程可行,輸出為1行整數,每個整數後一個空格,為n個子任務的編號,表示子任務的完成順序,如果有多種可能的順序,則輸出字典序最小者。

注:字典序,即物件在字典中的順序。對於兩個數字序列,從第一個數字開始比較,當某一個位置的數字不同時,該位置數字較小的序列,字典序較小,例如1 2 3 9比1 2 4 5小,1 2 8 9比1 2 10 3小。

輸入樣例1:
3 2
0 1
1 2
輸出樣例1:
0 1 2
輸入樣例2:
3 3
0 1
1 2
2 0
輸出樣例2:
unworkable project
程式碼長度限制
16 KB
時間限制
50 ms
記憶體限制
64 MB


拓撲排序,內容也是書上有的,簡單說,就是從沒有指著的點開始,把這個點彈出,並把點所連的點被連的標記數--,然後再從標記數0的點挑個點重複過程。

還有個字典序,無論字母、數字,是不是從前往後一個個比較,比如返回a < b,true則a字典序比b小。


G 關鍵路徑

分數 30
作者 朱允剛
單位 吉林大學
假定一個工程由若干子任務構成,使用一個包含n個頂點、e條邊的AOE網表示該工程,頂點編號為1至n,有向邊表示該工程的每個子任務,邊的權值表示完成該子任務所需的時間,假定網中只含一個源點和一個匯點。請編寫程式求出該工程的所有關鍵活動,並計算完成該工程所需的最短時間。

輸入格式:
每個測試點包含多組測試資料。每組資料第一行為2個整數n和e,均不超過200,分別表示AOE網的頂點數和邊數。接下來e行表示每條邊的資訊,每行為3個正整數a、b、c,其中a和b表示該邊的端點編號,c表示權值。各邊並不一定按端點編號順序排列,且各頂點並不一定按拓撲序排列。

輸出格式:
對每組資料,若工程不可行(AOE網中存在環),輸出“unworkable project”;若工程可行,則輸出第一行為完成工程所需的最短時間,並從第2行開始輸出關鍵活動,每個關鍵活動佔一行,格式為i->j,其中i和j表示關鍵活動所在邊的端點編號。各關鍵活動輸出順序為:按i的遞增順序輸出,若多個關鍵活動的i值相同,則按j的遞增順序輸出。

輸入樣例:
4 4
1 2 6
1 3 4
2 4 1
3 4 1

輸出樣例:
7
1->2
2->4

程式碼長度限制
16 KB
時間限制
100 ms
記憶體限制
64 MB


簡單的說,是計算最早完成時間與最晚完成時間相等的點,輸出即可。

回頭來看,這就是動態規劃啊


H 聯盟數目

分數 20
作者 朱允剛
單位 吉林大學
艾迪是一家集團公司的老闆,該集團包含n家公司,為了管理公司,艾迪會時常透過網路向各公司傳送訊息。各公司間的網路是單向的,每個公司都有一個分發列表,表示其能向哪些公司直接傳達訊息。例如A公司的分發列表為B、C,表示A可將訊息直接傳送給B和C(由於網路是單向的,B或C不一定能向A傳送訊息),這樣艾迪若想向A、B、C公司傳送訊息,則只需向A傳送訊息即可,隨後A可將訊息傳送到B和C。

為了便於管理各公司,艾迪打算將n家公司分成若干組,每組稱為一個區域聯盟,每組滿足如下條件:組內的任意公司訊息互相可達。即對於組內任意公司u和v,u可將訊息傳送到v(可由u直接傳送到v,也可透過組內其他公司中轉傳送到v),v也可將訊息傳送到u。可以認為一個公司可以將訊息傳送給自己,即一個公司可以自成一組。

艾迪希望組的數量儘可能少,即在滿足上述條件的情況下,每組包含的公司數目儘可能多。

現給定每個公司的分發列表,請編寫程式告知艾迪,他的集團最少能分成多少組。

輸入格式:
第一行包含一個整數T (1≤T≤100)表示資料組數。對於每組資料,第一行為一個整數n (2≤n≤100),表示公司數目,公司編號為1到n。隨後n行,第i行包含若干整數,表示第i個公司的分發列表,每行以0結尾。

輸出格式:
對於每組資料,輸出一行,為一個整數,表示組數。

輸入樣例:
3
5
2 4 3 0
4 5 0
0
0
1 0
3
2 0
0
2 1 0
3
2 0
3 0
0

輸出樣例:
3
3
3

程式碼長度限制
16 KB
時間限制
100 ms
記憶體限制
64 MB


這個點相對前面比較偏,實際上是要找到儘可能大的連通組,採用WarShall演算法,找到各個組的最大閉包。


小結

本次上機簡答考察了圖的基本使用,建立、遍歷、刪除等,然後又加了點場景考察迪傑斯特拉演算法和普利姆演算法,最後搞了應該比較難反應過來的WarShall演算法,算是把書上的內容過了一遍力,加油罷

相關文章