網路流問題的常見套路

2021-08-11 06:18:11 字數 1901 閱讀 3746

本文在接下來的一段時間內可能會經常擴充或修改,如有謬誤敬請諒解。[2017.11.24]

拆點,顧名思義,就是把乙個點拆成兩個點。因為在網路流的模型中,割特指邊集而非點集,所以想要實現「可以被割掉的點」,就用用到拆點思想。另外,這種方法也可以被理解為:使點同邊一樣有乙個容量上限。

把點a分成兩個,乙個叫a1,表示a的「入點」;另乙個叫a2,表示a的「出點」。a的所有出邊都從a2連出,所有入邊都連向a1。再連一條邊從a1指向a2,其邊權為點a的「點容量」。

例題:[usaco5.4]奶牛的電信(copy from 洛谷,特此表示感謝)

p1345 [usaco5.4]奶牛的電信telecowmunication

很不幸,有時候奶牛會不小心踩到電腦上,農夫約翰的車也可能碾過電腦,這台倒霉的電腦就會壞掉。這意味著這台電腦不能再傳送電郵了,於是與這台電腦相關的連線也就不可用了。

有兩頭奶牛就想:如果我們兩個不能互發電郵,至少需要壞掉多少臺電腦呢?請編寫乙個程式為她們計算這個最小值。

以如下網路為例:

1*/ 3 - 2*

這張圖畫的是有2條連線的3臺電腦。我們想要在電腦1和2之間傳送資訊。電腦1與3、2與3直接連通。如果電腦3壞了,電腦1與2便不能互發資訊了。

輸入格式: 第一行

四個由空格分隔的整數:n,m,c1,c2.n是電腦總數(1<=n<=100),電腦由1到n編號。m是電腦之間連線的總數(1<=m<=600)。最後的兩個整數c1和c2是上述兩頭奶牛使用的電腦編號。連線沒有重複且均為雙向的(即如果c1與c2相連,那麼c2與c1也相連)。兩台電腦之間至多有一條連線。電腦c1和c2不會直接相連。

第2到m+1行 接下來的m行中,每行包含兩台直接相連的電腦的編號。

輸出格式: 乙個整數表示使電腦c1和c2不能互相通訊需要壞掉的電腦數目的最小值。

樣例輸入:

3 2 1 2

1 3

2 3

樣例輸出:

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=605,inf=0x3f3f3f3f;

struct dinic;

vector

g[maxn];

vector

edges;

int cur[maxn],d[maxn];

bool vis[maxn];

void addedge(int f,int t,int c));

edges.push_back((edge));

int m=edges.size();

g[f].push_back(m-2);

g[t].push_back(m-1);

}bool bfs()}}

return vis[t];

}int dfs(int x,int a)

}return flow;

}int maxflow(int s,int t)

return flow;

}}dinic;

int main()

for(int i=1;i<=m;i++)

int mf=dinic.maxflow(c1+n,c2);

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

return

0;}

本題求至少要刪除多少個點使c1、c2不連通,問題的實質是乙個最小割,跑乙個最大流即可,因為只允許割點,不允許割邊,所以原有的邊邊權都為inf。點權為1,表示每個點最多只能被刪除一次。

常見網路流模型

描述 n 個人,每個人有乙個狀態,存在 m 對朋友,每個人可以翻轉狀態,求翻轉次數 衝突的朋友對數的最小值 模型 原點向 0 狀態的人連一條 inf 的邊,1 狀態向匯點連一條 inf 的邊,朋友之間連一條流量為 1 的邊,求最小割 描述 有 n 行,m 列,每個格仔上有乙個數,不能選任意兩個有公共...

網路流問題總結

這種一般遇到得比較少,除非是板題 這種問題一般是把全集分為兩類數,求分開這個集合 或是選出某個子集 的最小代價是多少。有關技巧 利用容量為inf的邊來干涉決策,如最大權閉合子圖 將所選集合的點的鄰接邊權求和分析,如最大密度子圖 判定s,t集合時必須用dfs 分數規劃 易錯點 cnt初始時沒有賦為1 ...

網路流 (網路流問題彙總)

網路 1 有乙個源點 s 和匯點 t 2 每一條有向邊e u,v 都有乙個容量限制記做c e 流 定義在網路弧集上的實值函式 f 滿足三個性質 1 對任意的弧 0 f c e 容量限制。2 f u,v f v,u 反對稱性。3 流守恆性 除源匯點外,其餘頂點都是過度點,流進頂點的流總和等於流出頂點的...