网络流
yangzichen1203 · · 算法·理论
Dinic 模版
#define inf (1ll<<60)
class Dinic{
private:
struct Edge{
int to,rev;
long long cap;
};
int n;
vector<vector<Edge>> g;
vector<int> dis,it;
bool bfs(int s,int t){
fill(dis.begin(),dis.end(),0);
queue<int> q;
dis[s]=1;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(auto &e:g[u]){
if(!dis[e.to]&&e.cap>0){
dis[e.to]=dis[u]+1;
q.push(e.to);
}
}
}
return dis[t]!=0;
}
long long dfs(int u,int t,long long f){
if(u==t) return f;
for(int &i=it[u];i<(int)g[u].size();i++){
Edge &e=g[u][i];
if(e.cap<=0) continue;
if(dis[e.to]!=dis[u]+1) continue;
long long push=dfs(e.to,t,min(f,e.cap));
if(push>0){
e.cap-=push;
g[e.to][e.rev].cap+=push;
return push;
}
}
return 0;
}
public:
Dinic(int n=0):n(n){
g.assign(n+1,{});
dis.assign(n+1,{});
it.assign(n+1,{});
}
void add(int u,int v,long long w){
int szu=g[u].size(),szv=g[v].size();
g[u].push_back({v,szv,w});
g[v].push_back({u,szu,0});
}
long long maxflow(int s,int t){
long long flow=0;
while(bfs(s,t)){
fill(it.begin(),it.end(),0);
while(1){
long long push=dfs(s,t,inf);
if(!push) break;
flow+=push;
}
}
return flow;
}
};
1
https://www.luogu.com.cn/problem/P1361
https://www.luogu.com.cn/problem/P1646
https://www.luogu.com.cn/problem/P4313 :::success[Solution] 很明显的二分图,考虑最小割。
对于点
如果割掉
| # 2 |
| https://www.luogu.com.cn/problem/P2057 |
| :::success[Solution] |
| 最小割。 |
对于选
对于点对
很显然这样建图后之间跑最小割即可。
| # 3 |
| https://www.luogu.com.cn/problem/P2774 |
https://www.luogu.com.cn/problem/P4474
:::success[Solution] 我们需要割掉一些点的贡献来保证方案合法,考虑最小割。
对于这种网格图相邻不能取的问题,可以将网格图的点
对于
对于不能取相邻点对,只需要建源点侧向汇点侧建边,所以当
4
https://www.luogu.com.cn/problem/P1402
https://www.luogu.com.cn/problem/P1231 :::success[Solution] 最大流。
每个人左侧连房间,容量为
| # 5 |
| https://www.luogu.com.cn/problem/P2598 |
| :::success[Solution] |
| 需要最小的代价将羊和狼隔开,想到最小割。 |
源点向狼连容量为
| 显然是对的,图就不画了。 |
|---|
| # 6 |
| https://www.luogu.com.cn/problem/P1791 |
https://www.luogu.com.cn/problem/P4174
https://www.luogu.com.cn/problem/P3749 :::success[Solution] 最大权闭合子图。
让收入减小量加上支出增加量最小,考虑最小割。
思想是如果我们割掉所有收入,我们就可以不割掉支出。
那么对于一个收入
答案就是
| # 7 |
| https://www.luogu.com.cn/problem/P4001 |
| :::success[Solution] |
| 平面图最小割。 |
平面图的最小割等于其对偶图的最短路,不需要跑网络流。
| 证明显然。 |
|---|
| # 8 |
| https://www.luogu.com.cn/problem/P5458 |
| :::success[Solution] |
| 先转换为两个独立维度的坐标,按 |
发现一定是一个
跑一遍最小割即可。
| # 9 |
| https://www.luogu.com.cn/problem/P6054 |
| :::success[Solution] |
| 可以预处理出第 |
考虑如何表示限制。每个人维护一条链
那么一个限制就可以表示为一些连接两条链的斜向边,如