單純最大流(兩個給定節點的最小割)問題的最優解法

2021-08-08 13:06:02 字數 1505 閱讀 8214

運用了各種不明所以的優化

反正我們會板子就行啦

然後再說幾點最大流的用處

因為反向邊的問題,所以最大流只能處理有向邊的問題

點i和點j的最大流其實是等於把點i和點j分開的最小割的

你想啊,從i到j有那麼多流量對吧

如果我想要讓i一滴水都留不到j

那麼我至少要割掉最大流那麼多的流量吧,具體證明。。。。我忘了,反正我等弱雞隊伍用個板子就行

還有乙個用處是在忘了那一場的網路賽上看到的

就是求兩個點的最小割的最小要割的邊的邊數

那麼假設有1000個點,我把每條邊的流量=原本的流量×1000+1

最後把得到的流量%1000就是最小的邊數了

這個很是有用啊感覺

那麼在求最大流的同時也把最短的邊數找出來了,真的是非常神奇

#include #include #include #include const int maxn = 1010;//點數的最大值

const int maxm = 400010;//邊數的最大值

const int inf = 0x3f3f3f3f;

struct edge

edge[maxm];//注意是maxm

int tol;

int head[maxn];

int gap[maxn], dep[maxn], pre[maxn], cur[maxn];

void init()

//加邊,單向圖三個引數,雙向圖四個引數

void addedge(int u, int v, int w, int rw = 0)

//輸入引數:起點、終點、點的總數

//點的編號沒有影響,只要輸入點的總數

int sap(int start, int end, int n)

u = start;

ans += min;

continue;

}bool flag = false;

int v;

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

}if (flag)

int min = n;

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

if (edge[i].cap - edge[i].flow && dep[edge[i].to] < min)

gap[dep[u]]--;

if (!gap[dep[u]])return ans;

dep[u] = min + 1;

gap[dep[u]]++;

if (u != start) u = edge[pre[u] ^ 1].to;

}return ans;

}int main()

int ans=sap(1,n,n);

printf("case %d: %d\n",k,ans);

}return 0;

}

網路的最大流最小割定理

什麼是流 flow 在乙個有向圖中,只有出去的邊沒有進來的邊的節點叫做源 source 只有進來的邊沒有出去的邊的節點叫做匯 sink 其它的節點進來的邊和出去的邊應該是平衡的。邊上可以加權值,假設對於乙個交通圖來說,可以認為邊上的權重為一條道路上的最大流量。那麼對於圖中任意兩個節點來說,它們之間可...

網路的最大流最小割定理

什麼是流 flow 在乙個有向圖中,只有出去的邊沒有進來的邊的節點叫做源 source 只有進來的邊沒有出去的邊的節點叫做匯 sink 其它的節點進來的邊和出去的邊應該是平衡的。邊上可以加權值,假設對於乙個交通圖來說,可以認為邊上的權重為一條道路上的最大流量。那麼對於圖中任意兩個節點來說,它們之間可...

最大流最小割定理與最小割的數學模型

一.最大流最小割定理.割 對於一張網路,我們稱乙個邊集的子集為乙個割,當且僅當去掉這個邊集的子集後源點s ss無法到達匯點ttt.最小割 邊權和最小的割被稱為最小割.最大流 最小割定理 一張網路的最大流等於其最小割的邊權之和.這個東西太經典了這裡就不證了.二.輸出一種最小割的方案.先跑一遍最大流得到...