網路最大流

2021-08-22 16:24:53 字數 1450 閱讀 2098

網路流就是網路流,無****說

證明:

∵對於任一割(s,t),s到t的流量f必定全部從這一割經過

∴|f|<=c(s,t)

又當圖中不存在增光路時,一定存在乙個割(s,t)的容量被流滿

即|f|=c(s,t)

∴f是f集合中最大的,c(s,t)是集合c中最小的,且f=c(s,t)

於是可以得到最小割等於最大流,且增光路演算法可以找到最小割,也就可以得到最大流。

考慮貪心dfs找有殘餘流量的一條s->t增光路,但該方法容易找到反例。

考慮給演算法反悔的方式,每次走完u->v,u-v剩餘容量-=w,加一條反邊v->u,其容量+=w,做同樣的尋找。這可以理解為下次走x->v->u->y的時候把流量從v退到u再從u流到y,同時用x到v的流量填補v的入流也就是本來v->u的流量。

演算法思想

考慮樸素演算法dfs找增光路每條邊利用一次有點浪費,於是用bfs改進,把找增廣路變成找增廣網。

先用bfs給網路分層,形成一條一條可走的路徑,同時判斷能不能走到t

dfs找增廣網,因為是網,所以到底傳回來了多少流量是要記flu+=dw的!!!!!

弧優化因為走u-v1的時候就已經把u-v1流量榨乾了,下次走u直接跳到下乙個v2,同時如果走完u沒能把上次傳下來的最小流量用完也就是在u出現了更窄的口子這次增廣中也不要再走u了。演算法實現上前者利用head的替身cur,後者令level_u=0。

**

bool bfs(int s,int t)}}

return0;}

int dfs(int u,int minw,int t)

}if(flu!=minw) lev[u]=0;

return flu;

}ll dinic(int s,int t)

演算法思想

和dinic同樣基於分層的思想,維護d[i]為結點i到結點t的最短距離,每次走d[u]==d[v]+1的邊,在跑增光路的過程中動態更新d[i]的值,從而節省bfs的時間。

小優化記num[i]為d為i的結點個數,出現斷層時退出

當前弧優化照樣,在走不動的時候重置

**

void bfs(int s,int t)

}}long

long augument(int s,int t)

u=t;

while(u!=s)

return minw;

}long

long isap(int s,int t)

bool flag=0;

for(int& i=cur[u];i!=-1;i=edge[i].next)

}if(!flag)

num[d[u]=m+1]++;

cur[u]=head[u];

if(u!=s) u=edge[p[u]].u; //易錯點}}

return ans;

}

模板 網路最大流 最大流

給出乙個網路圖,以及其源點和匯點,求出其網路最大流。in put role presentation inp utin put4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40ou tput role presentation out puto utpu t50最大...

模板 網路最大流 最大流

給出乙個網路圖,以及其源點和匯點,求出其網路最大流。in put role presentation inp utin put4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40ou tput role presentation out puto utpu t50最大...

網路最大流

1,一般增廣路演算法 採取標號法每次在容量網路中尋找一條增廣路進行增廣,直至不存在增廣路為止。增廣路方法 2,最短增廣路演算法 每個階段 在層次網路中,不斷用bfs演算法進行增廣直到 不存在增廣路為止。如果匯點不在層次網路中,則演算法中 止。3,連續最短增廣路演算法 在最短增廣路演算法的基礎上改造 ...