国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - floyd算法實現(xiàn)思路及實例代碼

floyd算法實現(xiàn)思路及實例代碼

2021-01-13 15:36C語言教程網(wǎng) C/C++

這篇文章主要介紹了floyd算法實現(xiàn)思路及實例代碼,有需要的朋友可以參考一下

正如我們所知道的,F(xiàn)loyd算法用于求最短路徑。Floyd算法可以說是Warshall算法的擴展,三個for循環(huán)就可以解決問題,所以它的時間復(fù)雜度為O(n^3)。

Floyd算法的基本思想如下:從任意節(jié)點A到任意節(jié)點B的最短路徑不外乎2種可能,1是直接從A到B,2是從A經(jīng)過若干個節(jié)點X到B。所以,我們假設(shè)Dis(AB)為節(jié)點A到節(jié)點B的最短路徑的距離,對于每一個節(jié)點X,我們檢查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,證明從A到X再到B的路徑比A直接到B的路徑短,我們便設(shè)置Dis(AB) = Dis(AX) + Dis(XB),這樣一來,當(dāng)我們遍歷完所有節(jié)點X,Dis(AB)中記錄的便是A到B的最短路徑的距離。

很簡單吧,代碼看起來可能像下面這樣:

 

復(fù)制代碼 代碼如下:

for ( int i = 0; i < 節(jié)點個數(shù); ++i )
{
    for ( int j = 0; j < 節(jié)點個數(shù); ++j )
    {
        for ( int k = 0; k < 節(jié)點個數(shù); ++k )
        {
            if ( Dis[i][k] + Dis[k][j] < Dis[i][j] )
            {
                // 找到更短路徑
                Dis[i][j] = Dis[i][k] + Dis[k][j];
            }
        }
    }
}

但是這里我們要注意循環(huán)的嵌套順序,如果把檢查所有節(jié)點X放在最內(nèi)層,那么結(jié)果將是不正確的,為什么呢?因為這樣便過早的把i到j(luò)的最短路徑確定下來了,而當(dāng)后面存在更短的路徑時,已經(jīng)不再會更新了。

讓我們來看一個例子,看下圖:

floyd算法實現(xiàn)思路及實例代碼

圖中紅色的數(shù)字代表邊的權(quán)重。如果我們在最內(nèi)層檢查所有節(jié)點X,那么對于A->B,我們只能發(fā)現(xiàn)一條路徑,就是A->B,路徑距離為9。而這顯然是不正確的,真實的最短路徑是A->D->C->B,路徑距離為6。造成錯誤的原因就是我們把檢查所有節(jié)點X放在最內(nèi)層,造成過早的把A到B的最短路徑確定下來了,當(dāng)確定A->B的最短路徑時Dis(AC)尚未被計算。所以,我們需要改寫循環(huán)順序,如下:

復(fù)制代碼 代碼如下:

for ( int k = 0; k < 節(jié)點個數(shù); ++k )
{
    for ( int i = 0; i < 節(jié)點個數(shù); ++i )
    {
        for ( int j = 0; j < 節(jié)點個數(shù); ++j )
        {
            if ( Dis[i][k] + Dis[k][j] < Dis[i][j] )
            {
                // 找到更短路徑
                Dis[i][j] = Dis[i][k] + Dis[k][j];
            }
        }
    }
}

這樣一來,對于每一個節(jié)點X,我們都會把所有的i到j(luò)處理完畢后才繼續(xù)檢查下一個節(jié)點。

那么接下來的問題就是,我們?nèi)绾握页鲎疃搪窂侥兀窟@里需要借助一個輔助數(shù)組Path,它是這樣使用的:Path(AB)的值如果為P,則表示A節(jié)點到B節(jié)點的最短路徑是A->...->P->B。這樣一來,假設(shè)我們要找A->B的最短路徑,那么就依次查找,假設(shè)Path(AB)的值為P,那么接著查找Path(AP),假設(shè)Path(AP)的值為L,那么接著查找Path(AL),假設(shè)Path(AL)的值為A,則查找結(jié)束,最短路徑為A->L->P->B。

那么,如何填充Path的值呢?很簡單,當(dāng)我們發(fā)現(xiàn)Dis(AX) + Dis(XB) < Dis(AB)成立時,就要把最短路徑改為A->...->X->...->B,而此時,Path(XB)的值是已知的,所以,Path(AB) = Path(XB)。

好了,基本的介紹完成了,接下來就是實現(xiàn)的時候了,這里我們使用圖以及鄰接矩陣:

復(fù)制代碼 代碼如下:


#define INFINITE 1000           // 最大值
#define MAX_VERTEX_COUNT 20   // 最大頂點個數(shù)
//////////////////////////////////////////////////////////////////////////

struct Graph
{
    int     arrArcs[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];    // 鄰接矩陣
    int     nVertexCount;                                 // 頂點數(shù)量
    int     nArcCount;                                    // 邊的數(shù)量
};
//////////////////////////////////////////////////////////////////////////
首先,我們寫一個方法,用于讀入圖的數(shù)據(jù):

void readGraphData( Graph *_pGraph )
{
    std::cout << "請輸入頂點數(shù)量和邊的數(shù)量: ";
    std::cin >> _pGraph->nVertexCount;
    std::cin >> _pGraph->nArcCount;

    std::cout << "請輸入鄰接矩陣數(shù)據(jù):" << std::endl;
    for ( int row = 0; row < _pGraph->nVertexCount; ++row )
    {
        for ( int col = 0; col < _pGraph->nVertexCount; ++col )
        {
            std::cin >> _pGraph->arrArcs[row][col];
        }
    }
}

接著,就是核心的Floyd算法:

復(fù)制代碼 代碼如下:

void floyd( int _arrDis[][MAX_VERTEX_COUNT], int _arrPath[][MAX_VERTEX_COUNT], int _nVertexCount )
{
    // 先初始化_arrPath
    for ( int i = 0; i < _nVertexCount; ++i )
    {
        for ( int j = 0; j < _nVertexCount; ++j )
        {
            _arrPath[i][j] = i;
        }
    }
    //////////////////////////////////////////////////////////////////////////

    for ( int k = 0; k < _nVertexCount; ++k )
    {
        for ( int i = 0; i < _nVertexCount; ++i )
        {
            for ( int j = 0; j < _nVertexCount; ++j )
            {
                if ( _arrDis[i][k] + _arrDis[k][j] < _arrDis[i][j] )
                {
                    // 找到更短路徑
                    _arrDis[i][j] = _arrDis[i][k] + _arrDis[k][j];

                    _arrPath[i][j] = _arrPath[k][j];
                }
            }
        }
    }
}


OK,最后是輸出結(jié)果數(shù)據(jù)代碼:

復(fù)制代碼 代碼如下:

void printResult( int _arrDis[][MAX_VERTEX_COUNT], int _arrPath[][MAX_VERTEX_COUNT], int _nVertexCount )
{
    std::cout << "Origin -> Dest   Distance    Path" << std::endl;

    for ( int i = 0; i < _nVertexCount; ++i )
    {
        for ( int j = 0; j < _nVertexCount; ++j )
        {
            if ( i != j )   // 節(jié)點不是自身
            {
                std::cout << i+1 << " -> " << j+1 << "\t\t";
                if ( INFINITE == _arrDis[i][j] )    // i -> j 不存在路徑
                {
                    std::cout << "INFINITE" << "\t\t";
                }
                else
                {
                    std::cout << _arrDis[i][j] << "\t\t";

                    // 由于我們查詢最短路徑是從后往前插,因此我們把查詢得到的節(jié)點
                    // 壓入棧中,最后彈出以順序輸出結(jié)果。
                    std::stack<int> stackVertices;
                    int k = j;

                    do
                    {
                        k = _arrPath[i][k];
                        stackVertices.push( k );
                    } while ( k != i );
                    //////////////////////////////////////////////////////////////////////////

                    std::cout << stackVertices.top()+1;
                    stackVertices.pop();

                    unsigned int nLength = stackVertices.size();
                    for ( unsigned int nIndex = 0; nIndex < nLength; ++nIndex )
                    {
                        std::cout << " -> " << stackVertices.top()+1;
                        stackVertices.pop();
                    }

                    std::cout << " -> " << j+1 << std::endl;
                }
            }
        }
    }
}


好了,是時候測試了,我們用的圖如下:

floyd算法實現(xiàn)思路及實例代碼

測試代碼如下:

復(fù)制代碼 代碼如下:

int main( void )
{
    Graph myGraph;
    readGraphData( &myGraph );
    //////////////////////////////////////////////////////////////////////////

    int arrDis[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];
    int arrPath[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];

    // 先初始化arrDis
    for ( int i = 0; i < myGraph.nVertexCount; ++i )
    {
        for ( int j = 0; j < myGraph.nVertexCount; ++j )
        {
            arrDis[i][j] = myGraph.arrArcs[i][j];
        }
    }

    floyd( arrDis, arrPath, myGraph.nVertexCount );
    //////////////////////////////////////////////////////////////////////////

    printResult( arrDis, arrPath, myGraph.nVertexCount );
    //////////////////////////////////////////////////////////////////////////

    system( "pause" );
    return 0;
}

如圖:

floyd算法實現(xiàn)思路及實例代碼

延伸 · 閱讀

精彩推薦
  • C/C++C語言實現(xiàn)電腦關(guān)機程序

    C語言實現(xiàn)電腦關(guān)機程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)電腦關(guān)機程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件...

    針眼_6702022-01-24
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進行了詳細(xì)的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實例之模擬計算器的相關(guān)資料,文中通過示...

    jia150610152021-06-07
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
主站蜘蛛池模板: 国产精品久久久久久久久久免费看 | 欧美人交a欧美精品 | 日本精品一区 | 黄色毛片在线看 | 精品久久久久久久久久久久久久久久久久久 | www.欧美日韩 | 国产精品69毛片高清亚洲 | 国产精品综合 | 久久久久一区二区三区 | 成人亚州 | 毛片黄片 | 婷色综合| 亚洲在线日韩 | 久久婷婷av| 亚洲成人中文字幕 | 久久成人a | 久久夜色精品国产 | 成人涩涩日本国产一区 | 亚洲在线视频 | 欧美一区二区三区在线看 | 免费午夜在线视频 | 欧洲成人在线 | 亚洲精品1区2区 | 欧美日韩在线一区二区 | 国产精品成人av | 日本黄色网址大全 | 蜜桃视频一区二区 | 羞羞视频在线播放 | 91亚洲国产成人久久精品网站 | 日韩欧美精品一区二区三区 | 成人在线视频观看 | 国产精品亚洲视频 | 一级黄色一级毛片 | 欧美性一区二区三区 | 在线免费观看av的网站 | 亚洲福利一区 | 国产精品久久精品 | 亚洲狠狠丁香婷婷综合久久久 | 欧美激情一区二区三级高清视频 | 亚洲精品久久久久久久久久久 | 在线久 |