最大流与最小割
POJ 3713: Transferring Sylla
网络流暴力做法:枚举起点终点作为源点和汇点,拆点建图,判断是否可以连续增广三次。
当然这样复杂度约为,肯定会TLE。
有人靠只枚举终点(固定0号点为起点)的方式AC了,但对于如下数据,似乎会出错。
3 6
0 1
0 1
0 1
0 2
0 2
0 2
正解如下:
引理:至少有三条独立路径(除去起点和终点相同)等价于图的点连通度(点连通图为至少删掉多少个点,使得图不连通)大于等于三。
形而上的理解:每删掉一个点,独立路径数就减一,因此两条件等价。
因此,只要枚举删掉一个点,然后判断剩下的图是否是点双联通的即可。(即是否存在割点,不存在,则可行)
具体实现上,求割点用tarjan即可。时间复杂度。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
网络流暴力做法:枚举起点终点作为源点和汇点,拆点建图,判断是否可以连续增广三次。
当然这样复杂度约为O(3n^2*m),肯定会TLE。
有人靠只枚举终点(固定0号点为起点)的方式AC了,但对于如下数据,似乎会出错。
3 6
0 1
0 1
0 1
0 2
0 2
0 2
正解如下:
引理:至少有三条独立路径(除去起点和终点相同)等价于图的点连通度(点连通图为至少删掉多少个点,使得图不连通)大于等于三。
形而上的理解:每删掉一个点,独立路径数就减一,因此两条件等价。
因此,只要枚举删掉一个点,然后判断剩下的图是否是点双联通的即可。(即是否存在割点,不存在,则可行)
具体实现上,求割点用tarjan即可。时间复杂度O(n*m)。
*/
#include
#include
#include
#include
#include
#include
POJ 2987: Firing
最大权闭合子图模板,这里不再赘述。
值得说到的是,最大权闭合子图模型跑完dinic后,从s出发能够访问到的点,都是被选择的点,同时点数满足最少。
因此只要从源点dfs一次,沿着所有没有满流的边能跑到的点集,就是答案集合。
最后,因为少了一个地方没有改成long long,WA了好久。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
最大权闭合子图模板,这里不再赘述。
值得说到的是,最大权闭合子图模型跑完dinic后,从s出发能够访问到的点,都是被选择的点,同时点数满足最少。
因此只要从源点dfs一次,沿着所有没有满流的边能跑到的点集,就是答案集合。
最后,因为少了一个地方没有改成long long,WA了好久。
*/
#include
#include
#include
#include
#include
#include
POJ 2914: Minimum Cut
求全局最小割,Stoer-Wagner算法。
题解链接:https://blog.csdn.net/yihuikang/article/details/7730986?locationNum=5
代码如下
/*
求全局最小割,Stoer-Wagner算法。
题解链接:https://blog.csdn.net/yihuikang/article/details/7730986?locationNum=5
*/
#include
#include
#include
#include
#include
#include
POJ 3155: Hard Life
01分数规划+最大密度子图,精度丧心病狂,二分的精度放到1e-8就会WA。
另外double的最大值取0x3f3f3f3f,不要取1e18,否则会WA,原因未知。
建图时,对于mid,化边为点(编号n+1~n+m+1),源点向n+i建边,容量1。
n+i向对应边的两个端点建边,容量INF。
i向汇点建边,容量mid。
最后判断m-最小割是否大于eps即可。
代码如下
/*
01分数规划+最大密度子图,精度丧心病狂,二分的精度放到1e-8就会WA。
另外double的最大值取0x3f3f3f3f,不要取1e18,否则会WA,原因未知。
建图时,对于mid,化边为点(编号n+1~n+m+1),源点向n+i建边,容量1。
n+i向对应边的两个端点建边,容量INF。
i向汇点建边,容量mid。
最后判断m-最小割是否大于eps即可。
*/
#include
#include
#include
#include
#include
#include
二分图匹配
POJ 1274: The Perfect Stall
二分图匹配模板题,不再赘述。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
二分图匹配模板题,不再赘述。
*/
#include
#include
#include
#include
#include
#include
POJ 2112: Optimal Milking
题目要求最大值尽量小,因此二分答案。
首先floyd跑出任意两点最短距离。
对于每个答案mid,在所有距离小于等于mid的、不属于同一集合的点之间建边。另外,源点向奶牛建边,容量为1。机器向汇点建边,容量为M。
接下来用dinic求一下这个二分图的多重匹配是否等于C即可。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
题目要求最大值尽量小,因此二分答案。
首先floyd跑出任意两点最短距离。
对于每个答案mid,在所有距离小于等于mid的、不属于同一集合的点之间建边。另外,源点向奶牛建边,容量为1。机器向汇点建边,容量为M。
接下来用dinic求一下这个二分图的多重匹配是否等于C即可。
*/
#include
#include
#include
#include
#include
#include
POJ 1486: Sorting Slides
题解链接:https://www.jianshu.com/p/4d3f099b0254
POJ 1466: Girls and Boys
由于分男女,所以是二分图,黑白染色后求一下最大独立集即可。
最大独立集=点数-最大匹配。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
由于分男女,所以是二分图,黑白染色后求一下最大独立集即可。
最大独立集=点数-最大匹配。
*/
#include
#include
#include
#include
#include
#include
POJ 3692: Kindergarten
二分图最大团问题,转化为求补图的最大匹配。答案就是G+B-补图的最大匹配。
原理:
转化为补图,补图中有边的说明是不认识的,那么想要剩下的人都认识,就得把边去掉,也就是去掉最少的点使所有的边都去掉,就是最小路径覆盖。
最小路径覆盖数等于最大二分配匹数。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
二分图最大团问题,转化为求补图的最大匹配。答案就是G+B-补图的最大匹配。
原理:
转化为补图,补图中有边的说明是不认识的,那么想要剩下的人都认识,就得把边去掉,也就是去掉最少的点使所有的边都去掉,就是最小路径覆盖。
最小路径覆盖数等于最大二分配匹数。
*/
#include
#include
#include
#include
#include
#include
POJ 2724: Purifying Machine
题意读懂后,剩下的就简单了。
在只有一位不同的字符串之间建边。
注意到每一条边连接的结点一个二进制位有奇数个1,另一个有偶数个1,故为二分图。
答案就是二分图的边覆盖数,即点数-最大匹配。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
题意读懂后,剩下的就简单了。
在只有一位不同的字符串之间建边。
注意到每一条边连接的结点一个二进制位有奇数个1,另一个有偶数个1,故为二分图。
答案就是二分图的边覆盖数,即点数-最大匹配。
*/
#include
#include
#include
#include
#include
#include
POJ 2226: Muddy Fields
比较巧妙的建图,蓝书上有,这里不赘述了。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
*/
#include
#include
#include
#include
#include
#include
最小费用流
POJ 3068: "Shortest" pair of paths
拆点建图,最后求流量为2的最小费用流即可。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
拆点建图,最后求流量为2的最小费用流即可。
*/
#include
#include
#include
#include
#include
#include
POJ 2195: Going Home
题解链接:https://www.jianshu.com/p/4d3f099b0254
POJ 3422: Kaka's Matrix Travels
经典的K取方格数,蓝书上有,这里不赘述了。
代码如下
/*
*/
#define method_1
#ifdef method_1
/*
*/
#include
#include
#include
#include
#include
#include