1. 程式人生 > >網路流入門 與 二分圖匹配 相關

網路流入門 與 二分圖匹配 相關

最大流

首先介紹的是網路流的基礎——最大流。
最大流,顧名思義,就是要讓網路中的總流量最大。

SAP&GAP

這裡,先講講SAP演算法+GAP優化
SAP演算法,其實就是在找增廣路的時候給每個點記錄一個高度標號,每次增廣只走兩邊的點的高度相差為1的邊(即滿足條件h[v]==h[u]+1的邊),且每次流完都用該點能走到的點的高度的最大值來更新該點的高度標號。該演算法的理論時間複雜度是O(n2m)的,但在實踐中,加了優化後,時間複雜度遠遠低於理論值,而且程式碼很短,是最實用的最大流演算法之一。
根據SAP演算法的特點,我們注意到,當某次增廣時,最大流可能已經求出,因此演算法做了很多無用功。這啟示我們若高度標號之間存在間隙,就說明不可能再有增廣路,演算法就可以提前終止。這就是GAP優化。事實證明,GAP優化使程式的效率提高了不少。

當前弧

其實還可以加上當前弧優化:
當前弧優化,就是指在增廣時給每個點記錄一條當前弧。然後,每次從當前弧開始增廣,每找到一條可行弧就把它設為該點的當前弧。當前弧優化的作用也是十分顯著的(尤其是稠密圖),有一道叫圈地計劃的題,GAP跑了953ms,幾乎是壓線過了,加上當前弧之後只跑了70ms。
現在給出SAP+GAP+當前弧優化的標程(以usaco草地排水為例):

#include<cstdio>
#include<algorithm>
const int N=1010,M=500010,INF=int(1e9);
int tot,to[M*2],next[M*2],head[N],tail[N];
int
m,n,S,T,c[N][N],h[N],vh[N]; using namespace std; void link(int u,int v) { to[++tot]=v; next[tot]=0; // if(!head[u]) head[u]=tot; else next[tail[u]]=tot; tail[u]=tot; //當前弧 } int aug(int v,int flow) { if(v==T) return flow; int minh=n+1; for(int i=head[v],j=tail[v];i;j=i,i=next
[i])//當前弧 { int u=to[i]; if(c[v][u]) { if(h[v]==h[u]+1) { int f=aug(u,min(flow,c[v][u])); if(f>0) { c[v][u]-=f; c[u][v]+=f; // next[tail[v]]=head[v]; next[j]=0; head[v]=i,tail[v]=j; //當前弧 return f; } if(h[S]>n) return 0; } minh=min(minh,h[u]+1); } } // if(--vh[h[v]]==0) h[S]=n+1; h[v]=minh; vh[h[v]]++; //GAP return 0; } int main() { int u,v,w; scanf("%d %d",&m,&n); S=1,T=n; for(int i=1;i<=m;i++) { scanf("%d %d %d",&u,&v,&w); if(!c[u][v]) link(u,v),link(v,u); c[u][v]+=w; } int ans=0; vh[0]=n; while(h[S]<=n) ans+=aug(S,INF); printf("%d",ans); }

最小割

割,顧名思義,就是要在圖中割掉一些邊。但是割掉的邊有限制條件:割完這些邊之後這個圖是“斷開”的,即沒有一條路徑能從S走到T。這些邊組成的邊集就是割。
使得割中的邊權和最小便是最小割。最小割模型也是一個非常重要的模型。
這裡不加證明地給出一個定理。

最小割=最大流

匈牙利演算法

#include<cstdio>
#include<algorithm>
#define N 1010
using namespace std;
int st,a[N][N],b[N],bz[N];
bool match(int v)
{
    if(bz[v]==st) return 0;
    bz[v]=st;
    for(int i=1;i<=a[v][0];i++)
    {
        int u=a[v][i];
        if(!b[u] || match(b[u]))
        {
            b[u]=v;
            return 1;
        }
    }
    return 0;
}
int main()
{
    int n,k,x,y,ans=0;
    scanf("%d %d",&n,&k);
    for(int i=1;i<=k;i++)
    {
        scanf("%d %d",&x,&y);
        y+=n;
        a[x][++a[x][0]]=y;
        a[y][++a[y][0]]=x;
    }
    for(st=1;st<=n;st++)
        if(match(st)) ans++;
    printf("%d",ans);
}

給點的顏色規定為黑、白兩種。用b[i]表示ib[i]進行了匹配。
現在講講思路:對於每個黑點v,都嘗試去匹配(它連出的點一定是白點,原因看定義)。如果它連向的白點u目前沒有匹配到,就說明當前匹配成功,b[u]=v;或者,嘗試把b[u]“趕走”,若能趕走,也說明匹配成功。否則說明匹配失敗。每匹配成功一次就把ans+1,最後ans就是最大匹配數。由於n個點全部匹配一遍,每次匹配最多走m條邊,所以時間複雜度是O(nm)

最小點(權)覆蓋問題

最小點(權)覆蓋

一個點可以覆蓋與它相鄰的邊。選出一些點,使得無向圖中的每條邊都被覆蓋,就是一個點覆蓋集。這個定義等價於讓每條邊連線的兩個頂點中至少選出一個。點覆蓋集是一個點集。而讓選出的點最少,就是最小點覆蓋集。讓選出的點的權值和最小,就是最小點權覆蓋集。這是經典的NPC問題。

二分圖的最小點(權)覆蓋問題的解決方法

這個問題的約束條件是邊:每條邊都要被覆蓋。把問題轉化成最小割模型。原圖中邊的關係不變。新增S,T點,S向X連邊,Y向T連邊((X,Y)E)。這樣一條從S到T的路徑必然是這樣的形式:S->u->v->T(uX,vY)。為了體現約束條件,可以令(S,u)的邊權為u點的點權。類似,令(v,T)的邊權為v點的點權。然後人為地讓(u,v)不在割中存在,即令(u,v)的邊權為+,這樣一條從S到T的路徑中(S,u),(v,T)兩邊必有一邊被割,這就剛好滿足了約束條件。而最小割恰好是最小化點權,所以這個最小割模型就是問題的答案。
不帶權,答案等於最大匹配

最大點權獨立集問題

最大點(權)獨立集

選出一些點,使這些點任意兩點在原無向圖中都不相鄰,選出的這些點就是一個獨立集。該定義的限制條件等價於對於(u,v)Eu,v不可同時在獨立集中。而點數最多的獨立集就是最大點獨立集。讓選出的點的權值和最大就是最大點權獨立集。這亦是經典的NPC問題

二分圖的最大點權獨立集問題的解決方法

可以證明,最大化點權獨立集等價於最小化點權覆蓋集。所以最大點權獨立集就可以用點權總和減去最小點權覆蓋集。感性理解起來挺顯然的233
不帶權,答案等於n-最大匹配

最小邊覆蓋

選擇邊,邊能覆蓋兩個端點。要求所有點都被覆蓋
聽說最小邊覆蓋=最大點獨立=n-最大匹配

最大權閉合子圖

定義:一個點帶權的有向圖,選出權值和最大的子圖,滿足圖中點的所有後繼也在子圖中
構圖:S向正權點連ai,負權點向T連|ai|,原圖中的邊容量為+
拿正權點權值和減去最小割就是答案

二分圖匹配

一些概念

圖的m染色:一個圖中,在保證每對相鄰的點的顏色都互不相同的前提下,使顏色總數為m的染色。
二分圖:一個圖可以2染色。
二分圖最大匹配:兩種不同顏色的點按圖中連的邊進行配對,配對過的點就不能再進行配對,這時要求成功配對的點對數最大。具體可以參考這兒

最小路徑覆蓋問題

用盡可能少的路徑覆蓋圖中所有點。

DAG的最小路徑覆蓋問題

最小不相交路徑覆蓋

DAG轉二分圖,每個點拆成X部,Y部,若DAG中存在邊a->b,二分圖中X部中的a向Y部的b連邊。
顯然答案等於n-最大匹配

最小可相交路徑覆蓋

一樣轉二分圖,只不過連邊是,只要x能到達y(不要求直接有邊相連),在二分圖中就連邊。
答案等於n-最大匹配

反鏈相關

反鏈定義:一個點集,其中兩兩點互不可達
根據Dilworth定理,最大反鏈=最小路徑覆蓋
Dilworth定理的對偶定理,最小反鏈覆蓋=最長路徑

丟連結跑

費用流

SPFA費用流

Created with Raphaël 2.1.2開始用SPFA跑出S到所有點的費用dis[i](只能走殘量大於0的邊)S能流到T嗎?修改殘量網路,計算答案結束yesno

每次跑SPFA的時候要記錄ST的路徑,然後流量顯然為路徑上殘量的最小值,記為minr。本次增廣總費用就是dis[T]minr(其實就是 每條邊的費用依次乘上流量 的總和)。

ZKW費用流

dis[i]表示

相關推薦

網路流入 二分匹配 相關

最大流 首先介紹的是網路流的基礎——最大流。 最大流,顧名思義,就是要讓網路中的總流量最大。 SAP&GAP 這裡,先講講SAP演算法+GAP優化。 SAP演算法,其實就是在找增廣路的時候給每個點記錄一個高度標號,每次增廣只走兩邊的點的高度

【POJ - 2226】Muddy Fields(匈牙利演算法 或 網路流dinic,二分匹配,最小點覆蓋,矩陣中優秀的建方式 )

題幹: Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 <= C <= 50). While good for the gra

二分匹配相關演算法及例題分析 最大匹配匈牙利演算法 最大權匹配KM演算法(二分型別問題彙總)

二分圖最大匹配: 問題描述:給出一個二分圖,找一個邊數最大的匹配。就是選擇儘量多的邊,使得選中的邊中任意兩條邊均沒有公共點。如果所有的點都是匹配點那就是一個完美匹配。 解決方案:增廣路定理 增廣

詳解匈牙利演算法二分匹配

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是演算法與資料結構專題的第31篇文章,我們一起來聊聊二分圖匹配與匈牙利演算法。 在上一篇文章當中我們介紹了一個有趣的穩定婚姻問題,模擬了男男女女配對的婚戀場景,並且研究了一下讓匹配更加穩定的Gale-Shapley演算法。如果錯過了

codevs 1922 騎士共存問題||二分||最大獨立集||二分匹配||Dinic匈牙利演算法的討論||網路

** 1922 騎士共存問題 ** ** 題目描述 Description ** 在一個n*n個方格的國際象棋棋盤上,馬(騎士)可以攻擊的棋盤方格如圖所示。棋盤 上某些方格設定了障礙,騎士不得進入。 對於給定的n*n個方格的國際象棋棋盤和

二分匹配問題(——模板習題總結)

什麽是 多個 習題 www. 最小路徑 覆蓋 最大 多少 .cn   首先得知道什麽是二分圖匹配問題,給出一個二分圖,每個人與另外的一個或者多個人存在某種關系     問將他們兩兩配對的對,最多能配成多少對。   其次,明確幾個專業名詞。     最大匹配:邊數最多的匹配成

【BZOJ2437】【NOI2011】兔兔蛋蛋(博弈論,二分匹配

路徑 gis 空格 都是 tps 找不到 oid AR 中移動 【BZOJ2437】【NOI2011】兔兔與蛋蛋(博弈論,二分圖匹配) 題面 BZOJ 題解 考慮一下暴力吧。 對於每個狀態,無非就是要考慮它是否是必勝狀態 這個直接用\(dfs\)爆搜即可。 這樣子對於每一次

BZOJ2437 [Noi2011]兔兔蛋蛋 【博弈論 + 二分匹配

read cls www 判斷 ring get 必須 out AI 題目鏈接 BZOJ2437 題解 和JSOI2014很像 只不過這題動態刪點 如果我們把空位置看做\(X\)的話,就會發現我們走的路徑是一個\(OX\)交錯的路徑 然後將圖二分染色,當前點必勝,當且僅當當

[bzoj3291] Alice能源計劃 (二分匹配)

i++ 一個 如果 name 字典 tin 滿足 tchar 超過 傳送門 Description 在夢境中,Alice來到了火星。不知為何,轉眼間Alice被任命為火星能源部長,並立刻面臨著一個嚴峻的考驗。為 了方便,我們可以將火星抽象成平面,並建立平面直角坐標系。火星上

BZOJ2437 NOI2011兔兔蛋蛋(二分匹配+博弈)

  首先將棋盤黑白染色,不妨令空格處為黑色。那麼移動奇數次後空格一定處於白色格子,偶數次後空格一定處於黑色格子。所以若有某個格子的棋子顏色與棋盤顏色不同,這個棋子就是沒有用的。並且空格與某棋子交換後,棋子所在的格子改變使得該棋子與棋盤顏色不同,那麼該棋子也會變為無用棋子。那麼問題變為空格在棋盤上黑白格子交替移

HDU ~ 4685 ~ Prince and Princess (二分匹配(網路流) + 強連通縮點)

題意 T組測試資料,每組先輸入n,m表示有n個王子和m個公主,接下來n行,每行先輸入k表示,第i個王子有K個喜歡的公主,然後輸入這k個公主的編號。每個王子只能和喜歡的妹子結婚,國王要求給他一個表,每個王子可以和幾個公主結婚,按序號升序輸出妹子的編號。這個表應滿足所有的王子最終都

網路流24題】最小路徑覆蓋問題-二分匹配/最大流

傳送門:luogu P2764 最小路徑覆蓋問題 題解 結論: D A G

網路流】【二分最大匹配】Buaacoding1043 難題·Beihang Couple Pairing Comunity 2017

難題·Beihang Couple Pairing Comunity 2017 時間限制: 2000 ms 記憶體限制: 131072 kb 總通過人數: 10 總提交人數: 15 題目描述 BCPC(Beihang Couple Pairing Community)2017 就要舉辦了!

【專題總結】網路二分(持續更新)

POJ 2112 大意 農夫約翰有 k 臺擠奶機和 c 只奶牛。任意兩個實體(擠奶機或奶牛)都在不同的地點,因此它們之間有相隔距離。每個擠奶機可以為 m 只奶牛擠奶。問怎樣分配擠奶機使得任意兩個實體之間的最長距離最小(每個奶牛都要分配到擠奶機,題目保證有

P1035 棋盤覆蓋 (二分匹配、最大網路流)

描述 給出一張n*n(n<=100)的國際象棋棋盤,其中被刪除了一些點,問可以使用多少1*2的多米諾骨牌進行掩蓋。 輸入格式 第一行為n,m(表示有m個刪除的格子) 第二行到m+1行為x,y,分別表示刪除格子所在的位置 x為第x行 y為第y列 

2018 BJTU Summer Training 【二分匹配 & 網路流 & 費用流】

前言(瞎BB) 網路流是我在OI生涯學的最後一個演算法,它很適合演算法競賽,因為它需要建立模型(圖)來反映題目中的限制條件,而且可以得出一些最優的東西(最大流),或者是搞出方案(搜尋殘量網路),這些都是演算法競賽最喜歡的。 高中就聽說過一位神犇,憑藉一手網路流解決了許多標

網路流】【二分多重匹配】【Hungary演算法】HDU 3605 Escape

【大意】有n個人和m個星球,每個人有想去的星球,星球有最大容納量,問能否給所有的人都安排上? 【思路】本來是最大流的題..但是n太大了,會T,看部落格說要用狀壓...就學了一波匈牙利演算法求二分圖最大匹配...狀壓的寫法有空補一補...          

[網路流] 二分匹配

二分圖匹配,本質上是最大流問題的一種特殊情況。 指派問題 有N臺計算機和K個任務,我們可以給每臺計算機分配一個任務,每臺計算機能夠處理的任務種類各不相同,請求出最多能夠處理的任務個數。 這個問題可以像下面這樣轉化為圖論模型來分析。我們可以像下面這樣來定義無

【洛谷2756】飛行員配對方案問題(二分匹配網路流24題)

前言 網路流24題還是要做完吧! 題解 這是一道模板題,這裡主要講一下怎麼匈牙利二分圖匹配: 對於左邊的列舉每一次選的左邊的人 對於右邊與他有連邊的那麼就是能換則換,不然就不換 最後統計出來的就是\(ans\) 差不多就是這樣子了吧。 #include<stdio.h>

【轉】一些論、網路流入題總結、彙總

最短路問題此類問題型別不多,變形較少 生成樹問題基本的生成樹就不放上來了 連通性,度數,拓撲問題此類問題主要牽扯到DFS,縮點等技巧 POJ 3352 - Road Const