「網路流博大精深」—sideman語最早知道網路流的內容便是最大流問題,最大流問題很好理解:乙個基本的網路流問題
感謝whd的大力支援
解釋一定要通俗!
如右圖所示,有乙個管道系統,節點,有向管道,即有向圖一張. [1]是源點,有無限的水量,[4]是匯點,管道容量如圖所示.試問[4]點最大可接收的水的流量?
這便是簡單的最大流問題,顯然[4]點的最大流量為50
死理性派請注意:流量是單位時間內的,總可以了吧!
然而對於複雜圖的最大流方法是什麼呢,有ek,dinic,sap,etc.下面介紹dinic演算法(看**的直接點這)
dinic演算法的基本思路:
根據殘量網路計算層次圖。引自nocow,相當簡單是吧…在層次圖中使用dfs進行增廣直到不存在增廣路
重複以上步驟直到無法增廣
小貼士:
一般情況下在dinic演算法中,我們只記錄某一邊的剩餘流量.
comzyh的較詳細解釋(流程) :
dinic動畫演示
用bfs建立分層圖 注意:分層圖是以當前圖為基礎建立的,所以要重複建立分層圖
用dfs的方法尋找一條由源點到匯點的路徑,獲得這條路徑的流量i 根據這條路徑修改整個圖,將所經之處正向邊流量減少i,反向邊流量增加i,注意i是非負數
重複步驟2,直到dfs找不到新的路徑時,重複步驟1
注意(可以無視):
對於反向弧(反向邊)的理解:
這一段不理解也不是不可以,對於會寫演算法沒什麼幫助,如果你著急,直接無視即可.
先舉乙個例子(如右圖):
必須使用反向弧的流網路
在這幅圖中我們首先要增廣1->2->4->6,這時可以獲得乙個容量為2的流,但是如果不建立4->2反向弧的話,則無
法進一步增廣,最終答案為2,顯然是不對的,然而如果建立了反向弧4->2,則第二次能進行
1->3->4->2->5->6的增廣,最大流為3.
comzyh對反向弧的理解可以說是」偷梁換柱「,請仔細閱讀:
在上面的例子中,我們可以看出,最終結果是1->2->5->6和1->2->4->6和
1->3->4->6.當增廣完1->2->4->5(代號a)後,在增廣
1->3->4->2->5->6(代號b),相當於將經過節點2的a流從中截流1(總共是2)走2->5>6,而不走2->4>6了,同時b流也從節點4截流出1(總共是1)走4->6而不是4->2->5->6,相當於ab流做加法.
簡單的說反向弧為今後提供反悔的機會,讓前面不走這條路而走別的路.
alwa同學非要我給他的文章加乙個鏈結,大家可以看看他的文章: 有關網路流中的反向弧和增廣路
dinic演算法的程式實現
最大流演算法一直有乙個入門經典題:poj 1273 或者是ucaco 4_2_1 來自nocow(中文) 這兩個是同乙個題
給出這道題的**
#include#include#include
#include
#include
using
namespace
std;
int edge[300][300];//
鄰接矩陣
int dis[300];//
距源點距離,分層圖
intstart,end;
int m,n;//
n:點數;m,邊數
intbfs()}}
if(dis[n]>0
)
return1;
else
return
0;//
匯點的dis小於零,表明bfs不到匯點}//
find代表一次增廣,函式返回本次增廣的流量,返回0表示無法增廣
int find(int x,int low)
}return0;
}int
main()
start=1
; end=n;
int ans=0
;
while(bfs())
printf(
"%d\n
",ans);
}return0;
}
KNN演算法 基本思想
knn k 最近鄰居 演算法 該演算法的基本思路是 在給定新文字後,考慮在訓練文字集中與該新文字距離最近 最相似 的 k 篇文字,根據這 k 篇文字所屬的類別判定新文字所屬的類別,具體的演算法步驟如下 step one 根據特徵項集合重新描述訓練文字向量 step two 在新文字到達後,根據特徵詞...
MVP基本思想
mvp的邏輯性思維都在p層,他降低了頁面的耦合度,具備低耦合的特性,mvp的出現使 更具邏輯性 首先我們看到分包的嚴謹性 mvp的結構分析 p層負責整體邏輯並且將m層和v層聯絡起來,m層主要負責 塊,callback將結果集返回p層,v層最後展示檢視 注意以下介面 public inte ce my...
git基本思想
git相比叫傳統的基於檔案svn優勢明顯,主要體現在天然分布式不怕丟失 不以檔案為為基礎,基於git的資料庫 commit雜湊健值檔案 的版本管理,分支 標籤等操作飛速,而不是緩慢地檔案和目錄操作 git下每個人都有乙個獨特的工作區和分支,不必實時和中心伺服器同步就可以 帶有社交性質的基於fork ...