3.5 网络流
最大流
从点s传输数据到t,每条边都有最大传输量(即边的容量),求最大传输量。
基础方法:Ford-Fulkerson,多次进行深度优先搜索寻找增广路,并更新残余网络(正向边减去这条路的流量,反向边增加),直至找不到增广路为止。
优化算法:Dinic,每次寻找最短的增广路。每次先进行一次BFS,考虑从近距离顶点指向远距离顶点的分层图,在上面DFS寻找最短增广路。此外需要注意的是,在进行DFS时,为了避免对一条边多次检查,需要当前弧优化。二分图最大匹配
两组顶点,组内不含边,求出最多的两两不含公共端点的边数。
构造两个虚拟顶点s和t,然后转化为最大流问题。可以根据二分图的性质,简化代码。
最小费用流
边上增加权值的信息,求流量为f时费用的最小值。
在残余网络上沿着最短路增广,由于有反向边,不用dijkstra求最短路,用Bellman-Ford。
两个处理器运行n个模块,每个模块在处理器A或B上执行都有所需的花费Ai或Bi。有m个相互之间需要数据交换的模块组合(ai,bi),如果在不同的处理器上会有额外花费wi。求执行所有模块的最小值。
在处理器A上执行的模块集合为S,在B上为T。从起点s向每个模块连一条Bi的边,从每个模块向终点连一条Ai的边,从ai向bi连一条wi的双向边。最大流。
poj 3281
共有F种食物,D种饮料。每头牛都有自己喜爱的食物和饮料,每种食物只能分配给一头牛,求最多有多少头牛能同时获得喜欢的食物和饮料。
建图,s->食物->牛->牛->饮料->t,即从s到所有的食物连一条边,从食物向喜爱它的牛连边,牛本身连一条边,牛到相应喜爱的饮料连边,饮料到t连边。求最大流。
n*n网格,k行星。一束光能消灭一整行或整列,求最少需要多少道光能全部消灭。
一共2N个光束选择(行N个,列N个)。把光束看做图的顶点,行星看做连接对应光束的边,最后的要求是求最小的顶点集合,是的每条边至少有一个光束中的顶点。
最小顶点覆盖,转化为二分图最大匹配。
n个玩具,由m个工厂加工。a[i,j]表示第i个玩具由第j个工厂加工的时间,每个工厂只能一个接一个加工玩具,求完成所有玩具时间的最小值。
若只有1个工厂,按照顺序a1,a2…,T=N*a1+(N-1)*a2+…+1*an。把每个机器拆成N个点,1~N分别代表某个玩具在这个机器上倒数第几个被加工。求最小费用流。