給定一個有N個頂點和E條邊的無向圖,請用DFS和BFS分別列出其全部的連通集。假設頂點從0到N−1編號。進行搜索時,假設咱們老是從編號最小的頂點出發,按編號遞增的順序訪問鄰接點。ios
輸入格式:
輸入第1行給出2個整數N(0<N≤10)和E,分別是圖的頂點數和邊數。隨後E行,每行給出一條邊的兩個端點。每行中的數字之間用1空格分隔。算法
輸出格式:
按照 ${v_1, v_2, ···, v_k}$ 的格式,每行輸出一個連通集。先輸出DFS的結果,再輸出BFS的結果。編程
輸入樣例:數組
8 6 0 7 0 1 2 0 4 1 2 4 3 5
輸出樣例:數據結構
{ 0 1 4 2 7 } { 3 5 } { 6 } { 0 1 2 7 4 } { 3 5 } { 6 }
#include <cstdio> #include <queue> #include <iostream> using namespace std; #define MAX 10 int a[MAX][MAX], dfs_visited[MAX], bfs_visited[MAX], N, E; //dfs_visited數組表示dfs queue<int> q; void dfs(int c){ dfs_visited[c] = 1; //1表示訪問過了 printf(" %d", c); for(int i = 0; i < N; i++) if(a[c][i] && !dfs_visited[i]) //利用二維數組的一行就是該節點的鄰接點,若是那個鄰接點還沒沒訪問過則遞歸訪問 dfs(i); } void bfs(int c){ bfs_visited[c] = 1; //1表示訪問過了 q.push(c); printf(" %d", c); while(!q.empty()){ //若是隊列不空則每次從隊列中取出一個節點找出該節點的第一層bfs節點,並加入隊列中 int temp = q.front(); q.pop(); for(int i = 0; i < N; i++){ //找出第一層bfs的節點,依次輸出並加入隊列,跟樹的層次遍歷很像 if(a[temp][i] && !bfs_visited[i]){ printf(" %d", i); bfs_visited[i] = 1; q.push(i); } } } } int main(){ int temp1, temp2; scanf("%d%d", &N, &E); for(int i = 0; i < E; i++){ scanf("%d%d", &temp1, &temp2); a[temp1][temp2] = 1; //由於是無向圖全部鄰接矩陣是關於主對角線對稱的 a[temp2][temp1] = 1; } for(int i = 0; i < N; i++){ if(!dfs_visited[i]){ putchar('{'); dfs(i); printf(" }\n"); } } for(int i = 0; i < N; i++){ if(!bfs_visited[i]){ putchar('{'); bfs(i); printf(" }\n"); } } return 0; }
哈利·波特要考試了,他須要你的幫助。這門課學的是用魔咒將一種動物變成另外一種動物的本事。例如將貓變成老鼠的魔咒是haha,將老鼠變成魚的魔咒是hehe等等。反方向變化的魔咒就是簡單地將原來的魔咒倒過來念,例如ahah能夠將老鼠變成貓。另外,若是想把貓變成魚,能夠經過念一個直接魔咒lalala,也能夠將貓變老鼠、老鼠變魚的魔咒連起來念:hahahehe。框架
如今哈利·波特的手裏有一本教材,裏面列出了全部的變形魔咒和能變的動物。老師容許他本身帶一隻動物去考場,要考察他把這隻動物變成任意一隻指定動物的本事。因而他來問你:帶什麼動物去可讓最難變的那種動物(即該動物變爲哈利·波特本身帶去的動物所須要的魔咒最長)須要的魔咒最短?例如:若是隻有貓、鼠、魚,則顯然哈利·波特應該帶鼠去,由於鼠變成另外兩種動物都只須要念4個字符;而若是帶貓去,則至少須要念6個字符才能把貓變成魚;同理,帶魚去也不是最好的選擇。數據結構和算法
輸入格式:
輸入說明:輸入第1行給出兩個正整數N (≤100)和M,其中N是考試涉及的動物總數,M是用於直接變形的魔咒條數。爲簡單起見,咱們將動物按1~N編號。隨後M行,每行給出了3個正整數,分別是兩種動物的編號、以及它們之間變形須要的魔咒的長度(≤100),數字之間用空格分隔。函數
輸出格式:
輸出哈利·波特應該帶去考場的動物的編號、以及最長的變形魔咒的長度,中間以空格分隔。若是隻帶1只動物是不可能完成全部變形要求的,則輸出0。若是有若干只動物均可以備選,則輸出編號最小的那隻。性能
輸入樣例:學習
6 11 3 4 70 1 2 1 5 4 50 2 6 50 5 6 60 1 3 70 4 6 60 3 6 80 5 1 100 2 4 60 5 2 80
輸出樣例:
4 70
本題能夠視爲一個無向帶權圖,題目裏以字符長度來衡量難度,所以帶鼠去,不管是變貓仍是變魚,都只須要4個字符。在輸入樣例中,第一行的6表明動物個數,即圖裏面頂點的個數,11表示邊的個數,接下來的每一行給出兩個頂點和它們之間的權重,這些數據對應一張無向的網圖。
本題的目的在於找出任意兩個頂點之間的最短路徑,用 FLoyd 算法。將圖用鄰接矩陣表示後,對每個頂點掃描它到其它頂點的最大值, 記錄下來,再在這些最大值裏找一個最小值,即咱們想要獲得的那個頂點。在本題中,也就是哈利應該帶該點所對應的動物去。這樣,咱們就成功的幫哈利完成了考試該帶什麼去的難題!
程序框架以下:
int main() { Graph G = BuildGraph(); //讀入圖 FindAnimal(G); //分析圖 return 0; }
#include<iostream> #include<fstream> using namespace std; //ifstream InFile("C:\\Users\\DELL\\Desktop\\in.txt",ios::in); #define MaxVertexNum 200 //最大頂點數設爲100 #define INFINITY1 65535 //∞設爲雙字節無符號整數的最大值65535 typedef int Vertex; //用頂點下標表示頂點,爲整形 typedef int WeightType; //邊的權值設爲整形 typedef char DataType; //頂點儲存的數據類型設爲字符型 //圖結點的定義 typedef struct GNode* PtrToGNode; struct GNode{ int Nv; //頂點數 int Ne; //邊數 WeightType G[MaxVertexNum][MaxVertexNum]; //鄰接矩陣 DataType Data[MaxVertexNum]; //存頂點的數據 //注意:若頂點無數據,此時Data[]能夠不出現 }; typedef PtrToGNode MGraph; //邊的定義 typedef struct ENode* PtrToENode; struct ENode{ Vertex V1,V2; //無向邊(v1,v2) WeightType Weight; //權重 }; typedef PtrToENode Edge; MGraph CreateGraph(int VertexNum) { MGraph Graph = new GNode; Graph->Nv = VertexNum; Graph->Ne = 0; for(int i=0;i<Graph->Nv+2 ;++i){ for(int j=0;j<Graph->Nv+2 ;++j){ Graph->G[i][j] = INFINITY1; } } return Graph; } void InsertEdge(MGraph Graph,Edge E) { Graph->G[E->V1][E->V2] = E->Weight; Graph->G[E->V2][E->V1] = E->Weight; } MGraph BulidGraph() { Vertex N,M; cin >> N>>M; Edge E=new ENode; MGraph Graph = CreateGraph(N); if(Graph->Nv >0){ for(int i=0;i<M;++i){ cin >> E->V1 >> E->V2 >> E->Weight; InsertEdge(Graph, E); } } return Graph; } //Floyd bool Floyd(MGraph Graph,WeightType D[][MaxVertexNum]) { for(int i=0;i<Graph->Nv +2;++i){ for(int j=0;j<Graph->Nv +2;++j){ D[i][j] = Graph->G[i][j]; } } for(int k=1;k<=Graph->Nv ;++k){ for(int i=0;i<=Graph->Nv ;++i){ for(int j=0;j<=Graph->Nv ;++j){ if(i!=j&&D[i][k]+D[k][j]<D[i][j]){ D[i][j] = D[i][k] + D[k][j]; if (i == j&&D[i][j]<0) { return false; } } } } } return true; } void FindAnimal(MGraph Graph) { WeightType D[MaxVertexNum][MaxVertexNum]; WeightType Max[MaxVertexNum]; Floyd(Graph, D); for(int i=1;i<=Graph->Nv ;++i){ int m = -1; for(int j=1;j<=Graph->Nv ;++j){ if(i!=j&&m<D[i][j]){ m = D[i][j]; } if(i!=j&&D[i][j]==INFINITY1){ cout << 0 << endl; return; } } Max[i] = m; } int ret = 1; for(int i = 2; i <= Graph->Nv; ++i){ //cout << Max[i] << endl; if(Max[ret]>Max[i]){ ret = i; } } cout << ret << " " << Max[ret] << endl; } int main() { MGraph Graph = BulidGraph(); FindAnimal(Graph); delete Graph; //InFile.close(); system("pause"); return 0; }
有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度、以及該公路要收取的過路費。如今須要你寫一個程序,幫助前來諮詢的遊客找一條出發地和目的地之間的最短路徑。若是有若干條路徑都是最短的,那麼須要輸出最便宜的一條路徑。
輸入格式:
輸入說明:輸入數據的第1行給出4個正整數N、M、S、D,其中N(2≤N≤500)是城市的個數,順便假設城市的編號爲0~(N−1);M是高速公路的條數;S是出發地的城市編號;D是目的地的城市編號。隨後的M行中,每行給出一條高速公路的信息,分別是:城市一、城市二、高速公路長度、收費額,中間用空格分開,數字均爲整數且不超過500。輸入保證解的存在。
輸出格式:
在一行裏輸出路徑的長度和收費總額,數字間以空格分隔,輸出結尾不能有多餘空格。
輸入樣例:
4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
輸出樣例:
3 40
這是一個圖論裏單源最短路徑問題,咱們用 Dijkstra 算法解決。這道題裏面城市爲結點,公路爲邊。一個複雜的問題是每一條邊的權重,在這道題裏有距離和收費兩種權重,首先要找距離意義上最短路徑,當最短路不止一條的時候,就須要找收費最短的路。
根據輸入樣例,有下面的圖:
綠色表示權重距離,紫色表示權重收費。咱們用基於 Dijkstra 算法的方法來解決,首先以距離爲權重應用 Dijkstra 算法,咱們知道到每收錄一個結點的時候要判斷其它結點有沒有被影響,會不會獲得一個更短的距離,若是更短的話咱們要更新這個距離,若是是等長的話,在本來的 Dijkstra 算法中就什麼都不作了,但在本題中,當距離相等的時候,咱們還須要按照收費來作一個更新。
#include<iostream> using namespace std; #define MaxNum 10000 typedef int ElemType; int main() { int N,M; ElemType S,D; cin>>N>>M>>S>>D; //用鄰接矩陣存儲圖 int **len = new int*[N]; //儲存公路長度 int **cost = new int*[N]; //儲存費用 for(int i=0; i<N; i++) { len[i] = new int[N]; cost[i] = new int[N]; } //初始化 for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { len[i][j] = MaxNum; cost[i][j] = MaxNum; } } //構建鄰接矩陣,處理輸入數據 for(int i=0;i<M;i++) { ElemType c1,c2; int l,c; cin>>c1>>c2>>l>>c; len[c1][c2] = l; len[c2][c1] = l; cost[c1][c2] = c; cost[c2][c1] = c; } //Dijastra算法開始 int *dist = new int[N]; //記錄當前路徑長度 int *acost = new int[N]; //記錄當前花費 //初始化 for(int i=0;i<N;i++) { dist[i] = MaxNum; acost[i] = MaxNum; } dist[S] = 0; acost[S] = 0; //進行算法 for(int k=0;k<2;k++) { for(int v=0;v<N;v++) { for(int w=0;w<N;w++) { if(dist[v] != MaxNum) { if(dist[v]+len[v][w] < dist[w]) dist[w] = dist[v] + len[v][w]; else if(dist[v] + len[v][w] == dist[w] && acost[v] != MaxNum && acost[v]+cost[v][w] <acost[w]) acost[w] = acost[v] + cost[v][w]; } } } } cout<<dist[D] << " " <<acost[D] <<endl; return 0; }
關於浙江大學MOOC數據結構課程的習題記錄就到這裏了,主要記錄了線性表、樹、圖的必作編程題內容,附上課程大綱:
第一講 基本概念(1:15:26)[陳越]1.1 什麼是數據結構(4節共32:43)
1.2 什麼是算法(3節共22:41)
1.3 應用實例:最大子列和問題(3節共20:02)
第二講 線性結構(2:19:00)[何欽銘]
2.1 線性表及其實現(6小節共45:04)
2.2 堆棧(4小節共39:51)
2.3 隊列(2小節共15:45)
2.4 應用實例:多項式加法運算(1小節10:37)
小白專場:多項式乘法與加法運算- C實現(3小節共27:43)
第三講 樹(上) (1:50:08)[何欽銘]
3.1 樹與樹的表示(5小節共38:54)
3.2 二叉樹及存儲結構(2小節共16:43)
3.3 二叉樹的遍歷(4小節共37:02)
小白專場:樹的同構 - C語言實現(2小節共17:29)
第四講 樹(中)(1:06:31)[何欽銘]
4.1 二叉搜索樹(3小節共20:57)
4.2 平衡二叉樹(2小節共22:53)
小白專場:是否同一棵二叉搜索樹- C實現(3小節共22:41)
線性結構之習題選講[陳越]:Reversing Linked List(3小節共13:08)
第五講 樹(下)(1:53:28)[何欽銘]
5.1 堆(4小節共30:05)
5.2 哈夫曼樹與哈夫曼編碼(3小節共19:52)
5.3 集合及運算(2小節共12:57)
小白專場:堆中的路徑 - C語言實現(1小節共7:51)
小白專場[陳越]:File Transfer - C語言實現(4小節共42:43)
第六講 圖(上)(1:29:32)[陳越]
6.1 什麼是圖(3小節共24:02)
6.2 圖的遍歷(4小節共22:22)
6.3 應用實例:拯救007(1小節共14:40)
6.4 應用實例:六度空間(1小節共8:06)
小白專場:如何創建圖- C語言實現(6小節共20:22)
第七講 圖(中)(2:11:35)[陳越]
樹之習題選講-Tree Traversals Again(2小節共12:16)
樹之習題選講-Complete Binary Search Tree(3小節共25:47)
樹之習題選講- Huffman Codes(3小節共18:11)
7.1 最短路徑問題(6小節共56:38)
小白專場:哈利•波特的考試- C語言實現(4小節共18:43)
第八講 圖(下)(57:02)[陳越]
8.1 最小生成樹問題(2小節共20:16)
8.2 拓撲排序(2小節共27:57)
圖之習題選講-旅遊規劃(2小節共8:49)
第九講 排序(上)(1:11:44)[陳越]
9.1 簡單排序(冒泡、插入)(4小節共23:26)
9.2 希爾排序(1小節共9:29)
9.3 堆排序(2小節共10:27)
9.4 歸併排序(3小節共28:22)
第十講 排序(下)(54:20)[陳越]
10.1 快速排序(4小節共25:25)
10.2 表排序(2小節共12:41)
10.3 基數排序(3小節共12:13)
10.4 排序算法的比較(1小節共4:01)
第十一講 散列查找(1:43:39)[何欽銘]
11.1 散列表(2小節共13:43)
11.2 散列函數的構造方法(2小節共13:05)
11.3 衝突處理方法(6小節共36:26)
11.4 散列表的性能分析(1小節10:26)
11.5 應用實例:詞頻統計(1小節6:01)
小白專場[陳越]:電話聊天狂人- C語言實現(4小節共23:58)
第十二講 綜合習題選講(30:12) [陳越]
習題選講-Insert or Merge(2小節共11:51)
習題選講-Sort with Swap(0,*)(2小節共11:06)
習題選講-Hashing - Hard Version(1小節共7:15)
最後給出一張數據結構和算法的思惟導圖:
剩下的內容將在以後的算法學習中進行。
參考連接:
06-圖1 列出連通集 (25分)
07-圖4 哈利·波特的考試(25 分)
旅遊規劃
$$$$不足之處,歡迎指正。