網路流24題

2022-01-31 23:18:07 字數 2748 閱讀 8818

學會網路流演算法後,我們要做的就是把問題轉化成網路流問題。

求二分圖最大匹配。

網路流建模要找到問題的關鍵特點,用連邊,流量(以及費用)把原問題轉化成網路流問題,包括最大流,最小割,費用流。

二分圖最大匹配的特點是每個點最多屬於一條匹配邊。這相當於是說,每個點只能流過一次。要求的是最大匹配,可以得出建模為:

最大流即為二分圖的最大匹配。

注意到這個解法中,我們實際上是把乙個匹配轉化成了1的流量,求出的最大流滿足每個點都只流過了一次,故符合匹配的定義。又因為是最大流,所以得到的是最大匹配。

#include#include#include#includeusing namespace std;

const int maxn=101;

const int inf=1e9+7;

const int maxm=1e4+1;

int que[maxn],d[maxn],ql,qr;

struct edge ;

struct graph

void add(int u,int v,int w) ;

h[u]=tot;

} bool bfs(int s,int t)

} return false;

} int dfs(int x,int t,int mx)

e[i].w-=tmp;

e[i^1].w+=tmp;

flow+=tmp;

mx-=tmp;

if (!mx) break;

} return flow;

} int maxflow(int s,int t)

return ret;

}} a;

int main()

求最大權閉合子圖,並輸出方案。

對於有向圖\(g\)的閉合圖\(s\)是指乙個\(g\)的乙個子圖滿足不存在\((u,v),u\in s,v\notin s\)。

最大權閉合子圖問題是指,每個點有點權,有正有負,求乙個閉合子圖使得其中的點權值最大。

對於選擇問題,可以考慮能否使用割的方法,因為乙個割把整個圖分成了兩部分,即選和不選。

現有的網路流模型可以解決最小割問題(最大流最小割定理),所以可以想辦法把這個問題變成最小割問題。由於要使點權最大,那麼我們可以把乙個東西減去最小割,得到答案。

我們把負權點的權值取絕對值。我們要的最大權閉合圖的權值\(w=選擇的正權點權值和-選擇的負權點權值和\)。

設\(sum=所有正權點權值和\),令\(c=sum-w=不選擇的正權點權值和+選擇的負權點權值和\),這樣我們不僅就化解了負權問題,而且得到了乙個漂亮的表達:不選的正的權值和+選擇的負的權值絕對值和。如果由於\(w\)要最大,\(sum\)是一定的,而且有\(w=sum-c\),所以我們只要令\(c\)最小即可。

建圖如下:

在這個圖上求最小割,一定不會割掉中間的邊。這是因為,割掉所有\((s,x)\)和\((y,t)\)必定是乙個合法的割。所以最小割一定小於這個值,所以不可能含有無限大。

所以這個割是乙個簡單割(所有割邊都直接連線\(s\)或\(t\))。這個簡單割把圖分成了兩部分,\(s\)集和\(t\)集。我們看看\(s\)集包含的點是什麼。

\(s\)集中的點,必定是沒有割開\((s,x)\)的點和割開了\((y,t)\)的點。也就是說,這個最小割的值就是我們的\(c\)

用總正權點和減去最小割就是答案啦。

這裡還要求輸出方案。我們要輸出的就是\(s\)集,也就是到最後\(s\)還可以到達的點,也就是dinic演算法中最後的層次圖。

#include#include#include#include#includeusing namespace std;

const int inf=1e9+7;

const int maxn=101;

const int maxm=1e4+1;

int read(int &x)

struct edge e[maxm<<3];

int h[maxn],tot=1;

void add(int u,int v,int w=0) ;

h[u]=tot;

} int que[maxn],ql,qr,d[maxn];

bool bfs(int s,int t)

} return false;

}int dfs(int x,int t,int mx)

e[i].w-=tmp;

e[i^1].w+=tmp;

flow+=tmp;

mx-=tmp;

if (!mx) break;

} return flow;

}int maxflow(int s,int t)

int a[maxn<<1];

int main() while (r);

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

int ans=maxflow(s,t);

for (int i=1;i<=n;++i) if (d[i]) printf("%d ",i);

puts("");

for (int i=n+1;i<=n+m;++i) if (d[i]) printf("%d ",i-n);

puts("");

printf("%d\n",sum-ans);

return 0;

}

網路流 24 題

1 搭配飛行員 題意 n個飛行員,其中有m名飛行員是正駕駛員。飛機每架有兩個駕駛員,需乙個正駕駛員和乙個副駕駛員。由於種種原因,例如相互配合的問題,有些駕駛員不能在同一架飛機上飛行,問如何搭配駕駛員才能使出航的飛機最多。思路 裸二分圖匹配 最大流 題 版本一 網路流做法 引入源點s 0以及匯點t n...

網路流24題

經典問題,做了一部分 太水的就不記錄了 最大流是對於一種完整的匹配的處理,一條路乙個貢獻。要求匹配盡可能多。費用流是對於乙個路徑的最值的處理,每條邊自己的費用。再匹配最多前提下,匹配的費用達到最值。難點就是對於條件狀態的設計 網路流24題 餐巾計畫問題 費用流建模 考慮每天一定有ri條髒毛巾,所以髒...

網路流24題

按馬的軌跡連邊,最後是一張二分圖,求最大匹配。可以跑匈牙利直接求出來,也可以連源點和匯點跑dinic。我是學二分圖的時候寫的,當時寫的是匈牙利。我當時碼風好奇怪 1 include 2 define id x,y x 1 n y 3 define new p p tmp ecnt 45 struct...