1. 程式人生 > >程式設計題—比較重量—Floyd演算法實現

程式設計題—比較重量—Floyd演算法實現

內容會持續更新,有錯誤的地方歡迎指正,謝謝!

何為Floyd演算法

是一種利用鄰接矩陣記錄每兩點間的最短路徑以在沒負迴路的有向圖中找到最短路徑的演算法。

求最短路的Floyd演算法框架:

宣告一個二維陣列(官方叫:鄰接矩陣),用於將有向圖轉化為這個二維陣列matrix,如何轉化?

  1. 先將對角線上的元素置0,非對角線上元素置無窮大;
  2. 再將圖中互相相連的兩點的距離寫入到二維陣列中;比如點1到點2的距離為3,則matrix[0][1] = 3;
  3. Floyd登場:見下方 Floyd分析 板塊

Floyd分析:

整個演算法雖然感覺很麻煩,但其實程式碼實現卻非常簡單,核心程式碼只有五行:

for(k=1;k<=n;k++)   
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
             //k為中轉點,matrix[i][k]表示從ik的路徑長度
             if(matrix[i][j]>matrix[i][k]+matrix[k][j])
                 matrix[i][j]=matrix[i][k]+matrix[k][j]; 

這五行程式碼的基本思想:傳遞思想,或叫中轉思想。最開始k=1,只允許經過1號頂點(必須經過1號頂點)進行中轉;接下來k=2,允許經過1和2號頂點(必須經過2號頂點)進行中轉……最後k=n,允許經過1~n號所有頂點(必須經過n號頂點)進行中轉,便可求得任意兩點之間的最短路程,至於經不經過除k號頂點以外的頂點,要根據實際輸入和每條路徑的最短長度的計算結果而定。
用一句話概括:最短路徑是從i號頂點到j號頂點只經過前k號點且必經過第k號結點的最短路程。

其實這是一種動態規劃的思想,動態規劃的特徵有兩個:

  1. 最優化問題;
  2. 把大問題轉化為一系列互相有關係的子問題,子問題的求解依賴於其它子問題的解。

動態規劃總結:就是根據每步計算的結果一步步地構造出了最優解決方案。

Floyd演算法的應用

全成對問題型別

比較重量問題型別

題目

小明陪小紅去看鑽石,他們從一堆鑽石中隨機抽取兩顆並比較她們的重量。這些鑽石的重量各不相同。在他們們比較了一段時間後,它們看中了兩顆鑽石g1和g2。現在請你根據之前比較的資訊判斷這兩顆鑽石的哪顆更重。

給定兩顆鑽石的編號g1,g2,編號從1開始,同時給定關係陣列vector,其中元素為一些二元組,第一個元素為一次比較中較重的鑽石的編號,第二個元素為較輕的鑽石的編號。最後給定之前的比較次數n。請返回這兩顆鑽石的關係,若g1更重返回1,g2更重返回-1,無法判斷返回0。輸入資料保證合法,不會有矛盾情況出現。

輸入例子:2,3,[[1,2],[2,4],[1,3],[4,3]],4
輸出例子:1

分析

依然是Floyd演算法的應用,與上個例子的不同點是初始值不同、if條件不同,思路如下:

鑽石之間的重量關係是一個有向無環圖,可宣告一個二維陣列(即鄰接矩陣),陣列元素的兩個索引分別代表前一個和後一個鑽石的重量,陣列元素是1代表前一個鑽石的重量大於後一個鑽石,是0代表尚未發現前後兩個鑽石之間的關係。那麼,如何將關係轉化為陣列?

  1. 將對角線上的元素置1,表示自己可到自己;非對角線上的元素置0,表示某點不可到某點;
  2. 根據已有的比較關係,將可比較(即第一個元素可到第二個元素)的兩點對應的元素置1,比如:若有[2,1],那2比1重,則有matrix[2][1]=1;
  3. Floyd登場:三個for迴圈,if(matrix[i][k]==1&&matrix[k][j]==1) matrix[i][j]==1;一波帶走!

程式碼

class Cmp {
public:
    int cmp(int g1, int g2, vector<vector<int> > records, int n) 
    {
        int i,j,k;
        //先要求得最重的那顆鑽石,又由於鑽石的重量各不相同,所以陣列索引為鑽石重量。
        int maxNum=0;
        for(i=0;i<n;++i)//由於records,此時i應初始化為0,判斷上界為<n
        {
            if(maxNum<records[i][0])
                maxNum=records[i][0];
            if(maxNum<records[i][1])
                maxNum=records[i][1];
        }
        int matrix[maxNum+1][maxNum+1];//多申請一個或幾個空間,以便從1開始,更直觀。
        for(i=1;i<=maxNum;++i)
            for(j=1;j<=maxNum;++j)
            {
                if(i==j)
                    matrix[i][i]=1;
                else
                    matrix[i][j]=0;
            }
        for(i=0;i<n;++i)//此時i應初始化為0,判斷上界為<n,而不是<maxNum
            matrix[records[i][0]][records[i][1]]=1;
        for(k=1;k<=maxNum;++k)
            for(j=1;j<=maxNum;++j)
                for(i=1;i<=maxNum;++i)
                    if(matrix[i][k]==1&&matrix[k][j]==1)
                        matrix[i][j]=1;
        if(matrix[g1][g2]==1)
            return 1;
        else if(matrix[g2][g1]==1)
            return -1;
        return 0;
    }
};

相關推薦

程式設計比較重量Floyd演算法實現

內容會持續更新,有錯誤的地方歡迎指正,謝謝! 何為Floyd演算法 是一種利用鄰接矩陣記錄每兩點間的最短路徑以在沒負迴路的有向圖中找到最短路徑的演算法。 求最短路的Floyd演算法框架: 宣告一個二維陣列(官方叫:鄰接矩陣),用於將有向圖轉化為這

幾種程式設計高難度常用演算法總結

筆試的程式設計題總是很頭疼,怕的有思路編不出來,作為一個半路出家健忘者,不得不記錄一些見得比較多的演算法,相信對以後筆試的程式設計題會有大大的幫助,話不多說,開始。 1.窮舉法 全排列: 比如一個

演算法比較重量

題目:小明陪小紅去看鑽石,他們從一堆鑽石中隨機抽取兩顆並比較她們的重量。這些鑽石的重量各不相同。在他們們比較了一段時間後,它們看中了兩顆鑽石g1和g2。現在請你根據之前比較的資訊判斷這兩顆鑽石的哪顆更重。給定兩顆鑽石的編號g1,g2,編號從1開始,同時給定關係陣列vector

迅雷2018演算法工程師-程式設計-python

1. 用x,y表示一個整數範圍區間,現在輸入一組這樣的範圍區間(用空格隔開),請輸出這些區間的合併。 輸入描述: 一行整數,多個區間用空格隔開。區間的逗號是英文字元。 輸出描述: 合併後的區間,用過空格隔開,行末無空格 ''' 1.首先按照x元素排序,把第一個區間存入

[計算機程式設計C++] Fibonaci數列的遞迴與非遞迴演算法實現

本文是對西安交通大學C++慕課第三章程式設計練習的16題的講解。 參考部落格:https://blog.csdn.net/zombie_slicer/article/details/38871799 題目內容: 編寫程式,顯示Fibonaci序列的前n項(從

LeetCode演算法-Same Tree(Java實現

這是悅樂書的第162次更新,第164篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第21題(順位題號是100)。給定兩個二叉樹,編寫一個函式來檢查它們是否相同。如果兩個二叉樹在結構上相同並且節點具有相同的值,則認為它們是相的。例如: 輸入: 1 1

LeetCode演算法-Symmetric Tree(Java實現

這是悅樂書的第163次更新,第165篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第22題(順位題號是101)。給定二叉樹,檢查它是否是自身的映象(即,圍繞其中心對稱)。 例如,這個二叉樹[1,2,2,3,4,4,3]是對稱的: 1 / \

劍指offer程式設計python實現(第2)替換空格

題目:替換空格 題目描述: 請實現一個函式,將一個字串中的每個空格替換成“%20”。 例如,當字串為We Are Happy.則經過替換之後的字串為We%20Are%20Happy。 python實現思路: 本題的實現思路很多,首先python中提供了很多處理字串的方法,替換字串直接

劍指offer程式設計python實現(第16)合併兩個排序的連結串列

劍指offer程式設計題python實現(第16題)合併兩個排序的連結串列 題目描述 輸入兩個單調遞增的連結串列, 輸出兩個連結串列合成後的連結串列, 當然我們需要合成後的連結串列滿足單調不減規則。 '''題目描述 輸入兩個單調遞增的連結串列, 輸出兩個連結串列合成後的連結串列, 當然我們需

演算法1:《招商銀行信用卡中心》(AI方向第一批)程式設計:L、R狀態改變

** 題目描述 **題目描述:用‘.’表示諾骨牌站立,‘L’表示該位置以前往左倒,‘R’表示該位置之後往右倒。 **如:…L… 得到的結果即為LLLLL…; …R… 得到的結果是…RRRR; # 如果L、R相遇,則各佔一半,剩餘的為.,如…R…L…得到的結果即為…

LeetCode演算法-Climbing Stairs(Java實現

這是悅樂書的第159次更新,第161篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第18題(順位題號是70)。你正在爬樓梯,它需要n步才能達到頂峰。每次你可以爬1或2步,你可以通過多少不同的方式登頂?注意:給定n是一個正整數。例如:

LeetCode演算法-Add Binary(Java實現

這是悅樂書的第157次更新,第159篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第16題(順位題號是67)。給定兩個二進位制字串,返回它們的總和(也是二進位制字串)。輸入字串都是非空的,只包含字元1或0。 例如: 輸入:a =“11”

LeetCode演算法-Plus One(Java實現

這是悅樂書的第156次更新,第158篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第15題(順位題號是66)。給定一個非空數字陣列來表示一個非負整數,並給其加1。該陣列已經排序,並且最高位有效數字位於陣列的開頭,並且陣列中的每個元素都表示單個數字。

LeetCode演算法-Min Stack(Java實現

這是悅樂書的第177次更新,第179篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第36題(順位題號是155)。設計一個支援push,pop,top和在恆定時間內檢索最小元素的堆疊。 push(x) - 將元素x推入堆疊。 pop() - 刪除堆疊頂部的元素。 to

LeetCode演算法-Rotate Array(Java實現

這是悅樂書的第184次更新,第186篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第43題(順位題號是189)。給定一個數組,將陣列向右旋轉k步,其中k為非負數。例如: 輸入:[1,2,3,4,5,6,7],k = 3 輸出:[5,6,7,1,2,3,4] 說明: 向右

LeetCode演算法-Reverse Bits(Java實現

這是悅樂書的第185次更新,第187篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第44題(順位題號是190)。給定32位無符號整數,求它的反轉位。例如: 輸入:43261596 輸出:964176192 說明:43261596以二進位制表示為00000010100

LeetCode演算法-House Robber(Java實現

這是悅樂書的第187次更新,第189篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第46題(順位題號是198)。你是一個專業的強盜,計劃在街上搶劫房屋。 每個房子都藏著一定數量的錢,阻止你搶劫他們的唯一限制因素是相鄰的房屋有連線的安全系統,如果兩

LeetCode演算法-Isomorphic Strings(Java實現

這是悅樂書的第191次更新,第194篇原創 01 看題和準備 今天介紹的是LeetCode演算法題中Easy級別的第50題(順位題號是205)。給定兩個字串s和t,確定它們是否是同構的。如果s中的字元可以替換為t,則兩個字串是同構的。 所有出現的字元必須替換為另一個字元,同時保留字元的順序。 沒有兩個

演算法程式設計-歸併排序

def mergesort(li): if len(li)==1: return li mid = len(li)//2 left = li[:mid]

演算法(十八):搜狗19年校招程式設計(一)——找區間

注:筆試時並沒有AC,線下修改後可以輸出示例結果。 問題:從一個序列中找出所有包含全部數字的最小索引區間,若有多個則按出現的順序輸出。 輸入輸出示例: 輸入:1 1 3 4 6 6 5 1 1 3 3 輸出:[2,7] [3,8] [4,9] 分析:先用一個list