運用了各種不明所以的優化
反正我們會板子就行啦
然後再說幾點最大流的用處
因為反向邊的問題,所以最大流只能處理有向邊的問題
點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.最小割 邊權和最小的割被稱為最小割.最大流 最小割定理 一張網路的最大流等於其最小割的邊權之和.這個東西太經典了這裡就不證了.二.輸出一種最小割的方案.先跑一遍最大流得到...