DS博客做業06--圖

1.本週學習總結

1.思惟導圖

2.談談你對圖結構的認識及學習體會。

經過對圖的學習,認識到了圖的兩種儲存方法,還有圖的深度遍歷和廣度遍歷。相對樹來講,本章學習的算法較多,如解決最小生成樹問題的Prime、Kruskal算法,最短路徑的Dijkstra、Floy算法。課後要及時鞏固複習,否則真的很容易混淆起來。不只要知道它們的原理,還要掌握算法的代碼。其中,我我的以爲,Prime算法會比Kruskal算法複雜一點,Prime算法隨着加入一個頂點,該頂點的最小邊可能就須要修改。而Kruskal算法只要依此找最小邊,確保它們不會出現迴路。
圖與樹並非絕不相關的兩種結構,在上述算法中,圖就轉化成樹來解決問題。樹和圖仍是挺類似的,都是結點與結點間相互聯繫,但圖的結構更復雜一些。圖的結構適合去解決像公路村村通的問題,道路就像一張網,每條路都是相連在一塊兒的。利用圖的結構去解決這類問題再合適不過了。

2.PTA實驗做業

2.1題目1: 圖着色問題

2.1.1設計思路(僞代碼)

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

2.1.2代碼截圖




2.1.3本題PTA提交列表說明。

Q1:計算顏色種數的時候出錯了,最大圖的測試點出現段錯誤
A1:輸入多組顏色數據後,count數組要初始化爲0,一開始的代碼爲color[502]={0},但發現並無將color數組初始化,就用循環將數組的每一個元素置爲0。段錯誤是由於沒有注意到題目的要求,color數組和count數組長度定義的過小了。

2.2題目2:六度空間

2.2.1設計思路(僞代碼)

定義全局變量
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結束循環
}

2.2.2代碼截圖



2.2.3本題PTA提交列表說明。

本來是用鄰接表作,提交後只有21分,一直有問題。就網上找了這個代碼,比原來的簡潔。把頂點的鄰接點進隊,用last,tail,level分別記錄當前層數的最後一個元素、下一層最後一個元素、層數,用這三個元素做爲尋找與每一個頂點每相距不超過6的結點,統計這些結點個數。只有當last等於隊頭元素時,level才自增,last才修改成tail,當level的值達到6,提早退出循環。

2.3題目3:公路村村通

2.3.1設計思路(僞代碼)

定義全局變量
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

2.3.2代碼截圖



2.3.3本題PTA提交列表說明。

Q1:部分正確
A1:數組g沒有設初值,致使在判斷輸入數據不足以保證暢通的狀況出現錯誤。該題採用Prime算法,參考了書上的代碼。但一開始沒有理解書上min=INF的意思,後來參考了同窗代碼,將min設爲不存在邊的g數組的值。經過循環,來判斷各個頂點與其餘頂點是否存在邊,既min的值有沒有被改變,從而輸出-1。

三、上機考試錯題及處理辦法

3.1截圖錯題代碼



3.2 錯的緣由及處理方法

這題按本身的作法只能部分正確,因而網上找了代碼,網上的代碼更簡潔,但沒有真正理解代碼,把if(last==x)、if(level==6)的這兩段代碼放到for循環中,發現輸出結果錯誤後,又把那兩段代碼放到if(visited[i]==0&&a[w][i]==1)裏面,結果仍是錯誤的。應該是先把全部頂點都入隊後,再開始後面的操做。因此if(last==x)、if(level==6)的這兩段代碼要放在for循環外面,問題就解決了。
相關文章
相關標籤/搜索