DS博客做業06--圖

1.思惟導圖及學習體會

1思惟導圖

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

  • 1. 在我看來,圖就是一堆頂點和邊的集合,既然是圖能夠分爲有向圖和無向圖、還能夠分爲連通圖和非連通圖。在圖結構中,每一個元素能夠有零個或多個前驅元素,也能夠有零個或多個後繼元素,也就是說元素之間的關係是多對多的。圖的存儲方法有鄰接矩陣和鄰接表,鄰接矩陣顧名思義,是一個矩陣,存儲着邊的信息的矩陣,而頂點則用矩陣的下標表示,若是是無向圖則有A [j ,i] = A[i, j],因此無向圖的鄰接矩陣是一個對稱矩陣;但若是是有向圖,則不必定是一個對稱矩陣。鄰接表能夠有效避免內存的浪費,鄰接表用一個一維數組存儲頂點,利用鄰接表建圖時候,須要建立多個結構體,如結點類型的結構體,頭結點也弄一個結構體,還有鄰接表一個結構體。兩種不一樣的存儲有各自的優缺點,適用於不一樣的地方。若是是稀疏圖或者須要特定用途的話採用領階矩陣存儲結構的好,反之若是是須要插入刪除等操做的話採用鄰接表的好。
  • 2.圖的遍歷有廣度優先遍歷BFS和深度優先遍歷DFS,不過書上給兩種算法的代碼對應的都是針對於連通圖的算法,還有最小生成樹的算法有prim算法和克魯斯卡爾算法,克魯斯卡爾算法的時間複雜度與邊e有關,克魯斯卡爾算法時間複雜度O(e^2),prim算法時間複雜度與圖的頂點n數有關,其時間複雜度爲O(n^2)。還有求最短路徑的算法:Dijkstra和Floyd算法,雖然Floyd算法更精短,但真是理解不來,時間複雜度也很多O(n^3),按老師所說的還算不錯了。
  • 3.圖的話結構體多了不少,光是要記住的類型名也不少,由於結構體多,因此有時候在調用一些結構體裏的數據時就容易搞錯,也由於Devc有時候不可以像vs那樣直接顯示結構體裏包含的成員,因此這段時間也改用vs來編寫代碼了,此次pta上的題目大均可以看書本上的代碼來寫,或改進些

2.PTA實驗做業

2.1.題目1:7-3 六度空間

「六度空間」理論又稱做「六度分隔(Six Degrees of Separation)」理論。這個理論能夠通俗地闡述爲:「你和任何一個陌生人之間所間隔的人不會超過六個,也就是說,最多經過五我的你就可以認識任何一個陌生人。」如圖1所示。
「六度空間」理論雖然獲得普遍的認同,而且正在獲得愈來愈多的應用。可是數十年來,試圖驗證這個理論始終是許多社會學家努力追求的目標。然而因爲歷史的緣由,這樣的研究具備太大的侷限性和困難。隨着當代人的聯絡主要依賴於電話、短信、微信以及因特網上即時通訊等工具,可以體現社交網絡關係的一手數據已經逐漸使得「六度空間」理論的驗證成爲可能。

假如給你一個社交網絡圖,請你對每一個節點計算符合「六度空間」理論的結點佔結點總數的百分比。

2.1.1設計思路(僞代碼)

宏定義鄰接矩陣g[10001][10001],頂點數v,邊數e,循環變量i,中間變量x,y用來輸入
main函數
   定義浮點型數據 n,m來求最後所佔比率
   輸入頂點數v和邊數e
   while e--   //構建鄰接矩陣
        輸入邊關係 x y
        g[x][y] = g[y][x] = 1
   end while
   for i=1 to v do
        n=v  
        m=bfs(i) //調用bfs函數
   end for
   return 0

int bfs(int z)
   定義數組vis[10001]=0 表示是否被訪問過的結點
   定義 last = z表示記錄每層的最後一個元素
   i定義tail表示用於記錄每一層壓入棧時的結點
   定義 level = 0 表示與該結點距離是否爲6
   定義count=1//表示結點
   建立int型棧q併入棧z
   將vis[z]置爲1表示訪問過了
   while q不爲空 
        z = q.front()//取棧頂元素於z
    q.pop()//去棧頂
    for i = 1to v do //廣度遍歷方法
        if g[z][i] 等於1 而且 vis[i]等於 0 then
                count++;
                vis[i] = 1;
                q.push(i);
                tail = i;
        end if 
         end for 
    if last 等於z then//一層所有從棧彈出,準備開始彈下一層,彈出的數等於當前層最後一個元素,並記錄與last 
        level++;
        last = tail;//記錄最後一個元素 
        end if 
        if  level 等於 6 break //符合題意的路徑節點       
    return count

2.1.2代碼截圖

2.1.3本題PTA提交列表說明。

  • Q1:起初覺得這是深度遍歷問題,想的是與這個結點距離爲6,那麼便從起點出發,一旦找到長度6的頂點便返回
  • A1:而後試了好幾回測試樣例都是錯的,問了舍友才知道應該用廣度遍歷,廣度遍歷的話找與起點有聯繫的點,並以此擴散,這樣能夠找到所有符合題意的點,而不是像深度遍歷同樣只能找一路
  • Q2:知道深度遍歷行不通,就將函數題的鄰接矩陣廣度遍歷拿來用,再慢慢改動點
  • A2:基本就是重寫代碼了,一堆宏定義都是是舍友教的,從編譯錯誤那裏開始就改爲了廣度遍歷法
  • Q3:提交pta,發現仍是不對,輸出出來的結果比起答案少不少
  • A3:在遍歷中,我沒有對一旦level等於6就退出循環,致使最後結果比起來少了不少

2.2.題目1:7-4 公路村村通

現有村落間道路的統計數據表中,列出了有可能建設成標準公路的若干條道路的成本,求使每一個村落都有公路連通所須要的最低成本。

2.2.1設計思路(僞代碼)

宏定義無窮大INF爲32767 及 MAXV 爲1001
宏定義鄰接矩陣 g[MAXV][MAXV]以及數組 visited[MAXV]={0};
定義 count 爲1來判斷是否爲符合要求
int main()
{
        定義 i,n,e分別表示循環變量、頂點數、邊數 
        定義浮點型數據 sum爲成本
    輸入 n,e //頂點數 邊數 
    if  n-1大於e then  //不符合的狀況 
        輸出-1
        return 0
    end if 
     CreateGraph(n, e)//建圖函數
     sum=Prim(n,1)//計算最低成本 調用prim函數 
    if count==n then 
    輸出sum
    else    輸出-1
   end if 
    return 0
}

void CreateGraph(int n, int e) //建立鄰接矩陣
{
    定義 i,j,a, b, c;
    for i = 0 to n; do//初始化
        for j = 0 to n do
            g[i][j]==0
                 end for
      end for
    for i = 1 to e do
          輸入 a,b,c
        g[a][b] =g[b][a]= c;
       end for
}

int Prim(int n, int v)
{
        定義 數組 lowcost[MAXV],close[MAXV], cost = 0表示最低成本, i, j表示循環變量 min爲最低的費用,index用來存下標
    for i = 1 to n //給lowcost數組和close數組置初值 
        lowcost[i] = g[v][i];
        close[i] = v; 
    end for
    for i = 1 to n  do
        min = INF
        定義 flag=0//用來判斷這一層是否有最低費用
        for j = 1to n //從剩下的城市中找最近的點 
            if lowcost[j] 不等於 0且lowcost[j] 小於 min)  then //計算費用最低 
                 min = lowcost[j];
                 index = j;
                 flag=1;
            end if 
        end for 
        if flag不爲0 then //該層有最低費用
            cost += min;
            count++;
        end if 
        lowcost[index] = 0;
        for j=1to n do  //進行調整      
            if lowcost[j] 不等於 0且g[index][j]小於lowcost[j then//修改數組的值             
                lowcost[j] = g[index][j];
                close[j] = index;
            end if 
        end for
    end for
    return cost;
}

2.2.2代碼截圖


2.2.3本題PTA提交列表說明。

  • Q1:若是沒法暢通的狀況處理不來
  • A1:後來在每次循環時候將最小min等於無窮大INF,若是最小的路徑等於無窮大,則說明沒有路徑即沒法正常暢通。
  • Q2:一開始是看書上的prim算法寫的,沒怎麼改動,主要是那個最低費用的一開始不知道怎麼寫,而後先試着提交一下仍是有分的
  • A2:後來我就設了min和index分別來存最少的路費和對應的點,並經過最後求一行的cost來計算最低費用
  • Q3:最後在第一層循環內有個地方錯誤
  • A3:就是要在每次要將index所在第一行初始化,就是lowcost[index]要置爲0,不然會錯誤,不能跳進循環

2.3.題目1:7-1 圖着色問題

圖着色問題是一個著名的NP徹底問題。給定無向圖G=(V,E),問能否用K種顏色爲V中的每個頂點分配一種顏色,使得不會有兩個相鄰頂點具備同一種顏色?

但本題並非要你解決這個着色問題,而是對給定的一種顏色分配,請你判斷這是不是圖着色問題的一個解。

2.3.1設計思路(僞代碼)

宏定義數組 visited[501]={0},d[501],k=0
宏定義鄰接矩陣a[501][501]及循環變量與一些變量:v,e,z,x,y,i,j,n;
void dfs(int i)
{
       定義 j;
       d[k++]=i;
       visited[i]=1;
       forj=1to v do       
           if(a[i][j]等於1 而且 visited[j]等於0 then dfs(j);
           end if
       end for
}
void dfs1()
{
    定義 i;
    for i=1 to v
    
         if visited[i]等於0 then dfs(i); //沒被訪問過
    end for
}

int main()
{
    輸入v、e、z;
    for i=0 to e
    
      輸入變關係x、y;
      a[x][y]=a[y][x]=1;
    end for
    dfs1();
    輸入n;
    while n--
   
     初始化 b[501]={0},c[501],e[501],sum=0,flag=1;
     for i=1 to v;i++)
     
        輸入c[i];
        b[c[i]]++;
        if b[c[i]]等於1 then sum++;
     end for 
     if sum不等於z then flag=0;
     end if
     for i=0 to k do e[i]=c[d[i]]
     end for
     for i=0 to k
     
         forj=0 to k     
        if a[d[i]][d[j]]等於1而且e[i]等於e[j] then
       
            flag=0;
            break;
       end if 
       
        if flag等於0 then break;
    end for 
     if flag等於0 輸出No
     else 輸出Yes
     end if 
end while  
 return 0
}

2.3.2代碼截圖




2.3.3本題PTA提交列表說明。

  • Q1:一開始提交中只有最小圖和最大圖正確
  • A1:在修改好屢次後仍是沒能獲得測試樣例的正確答案,最後實在是寫不動了,讓舍友教我,而後纔會寫的
  • Q2:舍友說這道題是廣度遍歷...我寫的是深度遍歷
  • A2:主要是經過dfs的遞歸調用來實現遍歷,原本我是寫的是廣度遍歷的,由於本身畫圖的時候本身是有點像廣度遍歷那樣,因此再寫代碼時候就覺得用深度遍歷,而後越搞越複雜,寫了百來行代碼,還搞不出來

3上機考試錯題及處理辦法

3.1.1截圖錯題代碼:6-2 jmu-ds-圖鄰接表操做

錯誤
算法

3.2 錯的緣由及處理方法

深度遍歷時候,指針指向下一個的時候,考試時候想錯了,而後放在了若是沒被遍歷過的if語句中,致使超時,將語句放在if語句外就能夠了

3.2.1截圖錯題代碼:6-3 jmu-ds-拓撲排序

錯誤
數組


3.2 錯的緣由及處理方法

改正微信



多是考試時候打得太快了...把大寫G寫成了小寫g,while也寫錯了,寫成了whlie...

3.1.1截圖錯題代碼:7-1 六度空間

錯誤

網絡

3.2 錯的緣由及處理方法

忘記用tail記錄下每行的最後一個沒被遍歷的數,還有當時看題目搞錯題目意思了,覺得少於6是當等於7時候退出循環,主要是考試前特別慌這最後一場考試,常常去寫去看這些pta代碼,基本到最後都快能背下來了,連變量名都沒換

3.1.1截圖錯題代碼:7-2 公路村村通

錯誤


函數

3.2 錯的緣由及處理方法

忘記考慮了另外就是當數目不對時候也是不符合的狀況,也要輸出-1,還有就是以前很差理解的將最後一個沒被遍歷的那一行的首個置爲0,在考試時候仍是沒注意到,又忘記了,最後仍是沒時間就沒去細想了
相關文章
相關標籤/搜索