学了几天感觉对网络流算是入门了,稍稍整理一下,同时在学习网络流的过程中看到了三篇别人很不错的blog(如下)
感谢 ~~
网络流相关定义及原理:https://www.cnblogs.com/rmy020718/p/9546071.html
Dinic算法+弧优化:https://www.cnblogs.com/SYCstudio/p/7260613.html
网络流常见建模方法:https://www.cnblogs.com/victorique/p/8560656.html
网络流关键的是图的建立,尤其是在匹配问题中,超级源点和汇点的建立和连接,再者就是对最大流算法的选择。
Dinic算法+弧优化
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn; //最大结点总个数
const int maxm; //最大边的总条数:注意要包括反向边个数,即总条数=正向边总条数*2
int s; //源点
int t; //汇点
int head[maxn]; //点u邻接表的第一条边
int cnt; //边的数量,从0开始编号
struct edge
{
int w; //边的流量(残量)
int to; //该边通向的结点v
int next; //点u邻接表的下一条边
}e[maxm];
void addedge(int u,int v,int w) //添加一条u->v,最大容量为w的边
{
//建立正向边
e[cnt].w=w;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
cnt++;
//建立反向边
e[cnt].w=0; //有些图是需要建立双向边(例如求最小割时),则反向边的初始残量不为0
e[cnt].to=u;
e[cnt].next=head[v];
head[v]=cnt;
cnt++;
}
int dis[maxn]; //dis数组记录层次
bool bfs() //利用BFS建立分成图,从而可以多次DFS增广
{
memset(dis,-1,sizeof(dis)); //初始化dis数组
queue<int> q;
q.push(s);
dis[s]=0; //源点层次为0
while(!q.empty())
{
int u=q.front();
q.pop()