初學網路流(超詳細) 保證弄懂

2021-07-26 20:33:21 字數 4293 閱讀 6286

最近在學習二分圖匹配,網路流和博弈論(%eazy,miaomiao,lsr_dalao,zyh,zlt),感謝諸位牛犇給蒟蒻的講課,讓我受益匪淺,ppt就不放上來了,有版權問題,下面我給大家談談我近期學習網路流的心得。(因為前幾天感冒落了些進度,感謝ergeda和腦屁股的細心輔導)。微笑吐舌頭

根據lsr_dalao的ppt上所言:

定義:

圖論中的一種理論與方法,研究網路上的一類最優化問題 。

很多系統中涉及流量問題,例如公路系統中車流量,網路中的資料資訊流,供油管道的油流量等。我們可以將有向圖進一步理解為「流網路」(flow network),並利用這樣的抽象模型求解有關流量的問題。

顯然我是有點沒看懂的,那我就用人類聽得懂的話來講講吧。比如我們有乙個交通網路如下圖

有點醜,不過忍受一下就好。qaq。我們假設1點是長沙,5點是北京,2,3,4分別是武漢,鄭州,石家莊,假設我們是坐火車北上,長沙到武漢的火車上只能坐兩個人(以此類推),中途不換程,不下車,從長沙出發的雅禮同學們只有多少能到北京呢?很顯然,是4個人。

如下圖:

藍色的數字代表火車上最多有幾個人,為什麼1->3是0?因為我們要求的是最大的人數,嗯,就是這樣。

依舊先引用lsr_dalao的ppt中話

1.簡介

求解網路流的基本思想就是每次尋找增廣路(就是源點到匯點的一條可行路)然後ans+=增廣路能流過的流量,更新剩餘網路,然後再做增廣路,直到做不出增廣路。關於網路流入門最難理解的地方就是剩餘網路了....為什麼在找到一條增廣路後...不僅要將每條邊的可行流量減去增廣路能流過的流量...還要將每條邊的反向弧加上增廣路能流過的流量.?..原因是在做增廣路時可能會阻塞後面的增廣路...或者說做增廣路本來是有個順序才能找完最大流的.....但我們是任意找的...為了修正...就每次將流量加在了反向弧上...讓後面的流能夠進行自我調整...剩餘網路的更新(就在原圖上更新就可以了)(what?speak earth language!)反正我是沒看懂的……..若有大神圍觀勿噴。

接下來蒟蒻給你們講講網路流最大流最簡單也是最慢的一種ek演算法:

我們設剛剛那個啥交通網路為圖g,這個圖是個有向圖,不然做不了,記住這句話,後面有題目。定義c函式為管道容量大小,就是火車上最多坐多少個人,f函式為管道的流量,就是火車身上現在做了幾個人。

顯然c函式要大於等於f函式的大小(不多說,水流多了管子會爆,其次,這是中國,不是印度,還是不能坐火車頂上的)。這是圖g的三個性質之一:容量限制,然後有個反對稱性,就是流過去的f = 流回來的-f,現在不懂沒事,一會講反向邊的時候細講,第三個就是流守恆性,就是從源點出發的總流量等於到匯點的總流量,就是從長沙出發的雅禮大佬們不能在火車上失蹤了。

明白了這些,我現在來講網路流中最難理解東西:反向邊

來個經典的圖:

還是很醜,嗯,有向圖吧,不多說了,初始是0號節點流向一號節點和四號節點(未畫出)1->2->5->6->7流量都是10,我們假設這條路徑上都是滿流,就是c = f 就是不能再流其他的流了,然後我們設定其他邊上也是c = 10,4->5也有5的流量,如果按照ek演算法中的bfs來說,為了找到乙個最大流,2->3這條邊都不會走,可能一開始找瓶頸把4,5入隊,但是後面不斷調整流量時,流量回被調成10,畢竟程式是為了尋找最大流,所以說如果不把流過的邊加上乙個反向邊4->5這個流量都不會被加入增廣路,可能你還是沒怎麼理解,我先來介紹下殘量網路,這樣你會理解的更深。

紅色的數字代表回流的量,2->3那條邊我先暫時不標,在殘留網路的中如果

f<

c 那麼就給它連一條回去的邊,先別問我為什麼,慢慢來。連回去的邊大小為增廣路上流量的大小,原來的邊為c-f,流量為0的邊不在殘量網路中出現。

現在我們再來講講反相邊到底是用來幹嘛的,你看,如果給2->5加一條反相邊,是不是4可以通過反相邊到達匯點7,而原來的圖是不行的因為5,6這條邊已經滿流,所以說,如果不加反相邊,會有一條路都找不到,那不就很尷尬了,^_^。

換句話說,加條反相邊那就是給程式乙個反悔的機會,現實中,反相邊是不存在的,只是在程式中出現,實際上,這就相當於4->5的流量轉給2->3,第一條路變成1,2,3,7,第二條路變成4,5,6,7,所以,是不是更好理解了呢?

接下來,我來講講ek的**。

//不要太在意**風格啦。

#include#include#include#include#include#include#define for(a,b,c) for(a=b;a<=c;a++)

#include#define inf 999999999

using namespace std;

const int maxn = 1010;

int rong[510][510],liu[510][510];

int p[maxn];

int m,n;

int pre[maxn];

int sum;

void internet()

while(c <= '9' && c >= '0')

return fg * sum;

}const int maxn = 1010;

int n,m;

int be[maxn], ne[maxn], to[maxn], e = 0, w[maxn];

int d[maxn];

void add(int x,int y,int z)

int bfs()}}

return d[1] != -1 ;

}int dfs(int x,int low)}}

return 0;

}int main()

int ans = 0,k;

while(bfs())

printf("%d\n",ans);}}

這裡只講最小費用流,只是講ek中的bfs換成了spfa,因為網路中的每條邊有了個費用。

#include#include#include#include#include#include#includeusing namespace std;

#define rep(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)

#define drep(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)

#define mem(a, b) memset((a), b, sizeof(a))

#define inf 999999999

int read()

while(c >= '0' && c <= '9')

return sum * fg;

}int n,m,num1 = 0,num2 = 0;

int be[100010], ne[100010], to[100010], c[100010], w[100010], e;

char s[200];

int pre[20010],id[20010],p[20010],d[20010];

struct t

h[10010],hm[10010];

void add(int x,int y,int ci,int wi)

bool spfa()}}

}}return d[num1+num2+1] < inf;

}int calc()

return sum;

}int main()

}rep(i, 1, num1)

rep(j,1,num2)

rep(i, 1, num1)add(0,i,1,0);

int k = num1 + num2 + 1;

rep(i,num1+1,num1+num2)add(i,k,1,0);

int ans = 0;

while(spfa())ans += calc();

printf("%d\n",ans);

}return 0;

}乙個模板,提供借鑑。

今後幾天我會發幾篇網路流好題的blog,希望大家看了有所收穫。

初學網路流

這個主題以前沒接觸過,覺得有點抽象,演算法有點不太清楚,看了一些部落格,下面,對這些部落格做些總結。具體參考這篇部落格的背景知識講解部分 具體到 之前 首先對網路流有了乙個初步的印象 然後一些概念性的定義,具體參考這篇部落格,對一些可能會影響到演算法理解的基礎概念進行掌握 然後接觸到演算法,顯示ff...

VMware上安裝Kali Linux 超詳細教程

1 建立新的虛擬機器 我們使用自定義的配置方法。2 新增映象檔案的路徑 3 選擇系統 4.輸入虛擬機器的名稱和安裝位置。5 處理器配置 6 記憶體分配 建議不要超過提示的最大推薦記憶體,這裡分配2gb。7 新增網路 8 繼續點選下一步,使用推薦選項,直至出現磁碟容量分配。一定要比建議分配容量大!一定...

中日電腦相關詞彙(超詳版)

參考 ascii ma 3 ascii code 安全 an 1 quan 2 security 安全漏洞 an 1 quan 2 lou 4 dong 4 security hole 安裝 an 1 zhuang 1 install sc c h 漢化版 han 4 hua 4 ban 3 中國語...