經過對圖的學習,認識到了圖的兩種儲存方法,還有圖的深度遍歷和廣度遍歷。相對樹來講,本章學習的算法較多,如解決最小生成樹問題的Prime、Kruskal算法,最短路徑的Dijkstra、Floy算法。課後要及時鞏固複習,否則真的很容易混淆起來。不只要知道它們的原理,還要掌握算法的代碼。其中,我我的以爲,Prime算法會比Kruskal算法複雜一點,Prime算法隨着加入一個頂點,該頂點的最小邊可能就須要修改。而Kruskal算法只要依此找最小邊,確保它們不會出現迴路。 圖與樹並非絕不相關的兩種結構,在上述算法中,圖就轉化成樹來解決問題。樹和圖仍是挺類似的,都是結點與結點間相互聯繫,但圖的結構更復雜一些。圖的結構適合去解決像公路村村通的問題,道路就像一張網,每條路都是相連在一塊兒的。利用圖的結構去解決這類問題再合適不過了。
int main 定義color數組存放每一個頂點的顏色 定義count數組 AdjGraph *G; 定義n,e,p,num,k 輸入n,e,p 調用CreateAdj函數 輸入顏色個數num for j=0 to num k=0; color數組初始化爲0 for i=1 to G->n { cin>>color[i]; count[color[i]]++; } 統計count數組中值不爲0的個數 if(k!=p) cout<<"No"<<endl; else { if(Judge(G,color)==1) cout<<"Yes"<<endl; else cout<<"No"<<endl; }
void CreateAdj 建立一個結點p,存放鄰接點,採用頭插法插入結點p int Judge 遍歷每一個頂點 判斷它的鄰接點中是否有和它顏色相同的 若是有就return 0 沒有就return 1
Q1:計算顏色種數的時候出錯了,最大圖的測試點出現段錯誤 A1:輸入多組顏色數據後,count數組要初始化爲0,一開始的代碼爲color[502]={0},但發現並無將color數組初始化,就用循環將數組的每一個元素置爲0。段錯誤是由於沒有注意到題目的要求,color數組和count數組長度定義的過小了。
定義全局變量 int n,m; int count; int a[10001][10001]={0}; int main { 定義 i,b,c; 輸入n,m for i=0 to m 輸入b,c a[b][c]=1; a[c][b]=1; for i=1 to n count=1; 調用函數BFS(i); 輸出結點數佔結點總數的百分比 }
void BFS(int x) 定義數組visited 定義隊列q 定義i,j 定義level = 0 記錄層數 定義last = x 記錄當前層數的最後一個元素 定義tail 指向下一層最後一個元素 把x入隊 visited[x]=1 while(!q.empty()) { 取隊頭元素x x出隊 for i=1 to n { if visited[i]==0&&a[x][i]==1 count++; tail=i; visited[i]=1; i進隊 } if last==x level自增 修改last的值爲tail 若是level等於6結束循環 }
本來是用鄰接表作,提交後只有21分,一直有問題。就網上找了這個代碼,比原來的簡潔。把頂點的鄰接點進隊,用last,tail,level分別記錄當前層數的最後一個元素、下一層最後一個元素、層數,用這三個元素做爲尋找與每一個頂點每相距不超過6的結點,統計這些結點個數。只有當last等於隊頭元素時,level才自增,last才修改成tail,當level的值達到6,提早退出循環。
定義全局變量 int s=0,n,e; int g[4000][4000]; int lowcost[4000],closest[4000]; int main { 輸入n,e 調用函數CreateMGraph(n,e) if(Prim(1)==1) 輸出s else 輸出-1 }
void CreateMGraph(int n,int e ) 定義i,j,a,b,c 數組全部元素初始化爲9999 for i=1 to e 輸入a,b,c g[a][b]=c; g[b][a]=c; g[i][i]=0;
int Prim(int v) 定義min,i,j,k; for i=1 to n { lowcost[i]=g[v][i]; closest[i]=v; } for i=1 to n { min=9999; for j=1 to n { 若是 lowcost[j]的值不爲0且小於min min=lowcost[j]; k=j; } if min==9999 返回0 s+=min; 標記k已經加入U lowcost[k]置爲0 for j=1 to n 若是g[k][j]的值不爲0且小於lowcost[j]就對頂點進行調整 lowcost[j]=g[k][j]; closest[j]=k; } 返回1
Q1:部分正確 A1:數組g沒有設初值,致使在判斷輸入數據不足以保證暢通的狀況出現錯誤。該題採用Prime算法,參考了書上的代碼。但一開始沒有理解書上min=INF的意思,後來參考了同窗代碼,將min設爲不存在邊的g數組的值。經過循環,來判斷各個頂點與其餘頂點是否存在邊,既min的值有沒有被改變,從而輸出-1。
這題按本身的作法只能部分正確,因而網上找了代碼,網上的代碼更簡潔,但沒有真正理解代碼,把if(last==x)、if(level==6)的這兩段代碼放到for循環中,發現輸出結果錯誤後,又把那兩段代碼放到if(visited[i]==0&&a[w][i]==1)裏面,結果仍是錯誤的。應該是先把全部頂點都入隊後,再開始後面的操做。因此if(last==x)、if(level==6)的這兩段代碼要放在for循環外面,問題就解決了。