最大权闭合子图 分类: bzoj poj templates 2015-08-06 16:54 11人阅读 评论(0) 收藏
2015-08-06 16:54
302 查看
参考论文:胡伯涛《最小割模型在信息学竞赛中的应用》
闭合子图的定义:
定义一个有向图 G=(V,E) 的闭合图是该有向图的一个点集,且该点集的所有出边指向的点属于该点集,即闭合图内的任意点的任意后继也一定在闭合图中。
如何求解最大权闭合子图? 用最小割来解决。
题目:poj 2987 bzoj 1497 hdu 3879
poj 2987
构图:
bzoj 1497
构造二分图,将原图中的边视为X侧点,点视为Y侧点,它们构成依赖关系。
如果看不懂胡伯涛的论文,可以参考以下证明:
最大权闭合图证明:
首先引入结论,最小割所产生的两个集合中,其源点S所在集合(除去S)为最大权闭合图,接下来我们来说明一些结论。
证明:最小割为简单割。
引入一下简单割的概念:割集的每条边都与S或T关联。(请下面阅读时一定分清最小割与简单割,容易混淆)
那么为什么最小割是简单割呢?因为除S和T之外的点间的边的容量是正无穷,最小割的容量不可能为正无穷。所以,得证。
证明网络中的简单割与原图中闭合图存在一一对应的关系。(即所有闭合图都是简单割,简单割也必定是一个闭合图)。
证明闭合图是简单割:如果闭合图不是简单割(反证法)。那么说明有一条边是容量为正无穷的边,则说明闭合图中有一条出边的终点不在闭合图中,矛盾。
证明简单割是闭合图:因为简单割不含正无穷的边,所以不含有连向另一个集合(除T)的点,所以其出边的终点都在简单割中,满足闭合图定义。得证。
证明最小割所产生的两个集合中,其源点S所在集合(除去S)为最大权闭合图。
首先我们记一个简单割的容量为C,且S所在集合为N,T所在集合为M。
则C=M中所有权值为正的点的权值(即S与M中点相连的边的容量)+N中所有权值为负的点权值的绝对值(即N中点与T中点相连边的容量)。记(C=x1+y1);(很好理解,不理解画一个图或想象一下就明白了)。
我们记N这个闭合图的权值和为W。
则W=N中权值为正的点的权值-N中权值为负的点的权值的绝对值。记(W=x2-y2);
则W+C=x1+y1+x2-y2。
因为明显y1=y2,所以W+C=x1+x2;
x1为M中所有权值为正的点的权值,x2为N中权值为正的点的权值。
所以x1+x2=所有权值为正的点的权值之和(记为tot).
所以我们得到W+C= tot.整理一下 W = tot-C.
到这里我们就得到了闭合图的权值与简单割的容量的关系。
因为tot为定值,所以我们欲使W最大,即C最小,即此时这个简单割为最小割,此时闭合图为其源点S所在集合(除去S)。得证。
至此,我们就将最大权闭合图问题转化为了求最小割的问题。求最小割用最小割容量=最大流,即可将问题转化为求最大流的问题。
闭合子图的定义:
定义一个有向图 G=(V,E) 的闭合图是该有向图的一个点集,且该点集的所有出边指向的点属于该点集,即闭合图内的任意点的任意后继也一定在闭合图中。
如何求解最大权闭合子图? 用最小割来解决。
题目:poj 2987 bzoj 1497 hdu 3879
poj 2987
构图:
void build() { S = n + 1, T = n + 2, ind = n + 2; for(int i = 1, e; i <= n; i++) { read(e); if(e > 0) NewEdge(S, i, e), tot += e; else if(e < 0) NewEdge(i, T, -e); else; } for(int i = 1, u, v; i <= m; i++) { read(u), read(v); NewEdge(u, v, LINF); } }
bzoj 1497
构造二分图,将原图中的边视为X侧点,点视为Y侧点,它们构成依赖关系。
void init() { std::cin >> n >> m; S = n + m + 1, T = n + m + 2, ind = T; for(int i = 1; i <= T; i++) head[i] = Nya; for(int i = 1, cost; i <= n; i++) read(cost), NewEdge(i, T, cost); for(int i = 1; i <= m; i++) { int u, v, w; read(u), read(v), read(w); NewEdge(S, n + i, w), ans += w; NewEdge(n + i, u, INF); NewEdge(n + i, v, INF); } } int main() { #ifndef ONLINE_JUDGE freopen("bzoj1497.in","r",stdin); freopen("bzoj1497.out","w",stdout); #endif init(); ans -= dinic.main(); std::cout << ans; #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
如果看不懂胡伯涛的论文,可以参考以下证明:
最大权闭合图证明:
首先引入结论,最小割所产生的两个集合中,其源点S所在集合(除去S)为最大权闭合图,接下来我们来说明一些结论。
证明:最小割为简单割。
引入一下简单割的概念:割集的每条边都与S或T关联。(请下面阅读时一定分清最小割与简单割,容易混淆)
那么为什么最小割是简单割呢?因为除S和T之外的点间的边的容量是正无穷,最小割的容量不可能为正无穷。所以,得证。
证明网络中的简单割与原图中闭合图存在一一对应的关系。(即所有闭合图都是简单割,简单割也必定是一个闭合图)。
证明闭合图是简单割:如果闭合图不是简单割(反证法)。那么说明有一条边是容量为正无穷的边,则说明闭合图中有一条出边的终点不在闭合图中,矛盾。
证明简单割是闭合图:因为简单割不含正无穷的边,所以不含有连向另一个集合(除T)的点,所以其出边的终点都在简单割中,满足闭合图定义。得证。
证明最小割所产生的两个集合中,其源点S所在集合(除去S)为最大权闭合图。
首先我们记一个简单割的容量为C,且S所在集合为N,T所在集合为M。
则C=M中所有权值为正的点的权值(即S与M中点相连的边的容量)+N中所有权值为负的点权值的绝对值(即N中点与T中点相连边的容量)。记(C=x1+y1);(很好理解,不理解画一个图或想象一下就明白了)。
我们记N这个闭合图的权值和为W。
则W=N中权值为正的点的权值-N中权值为负的点的权值的绝对值。记(W=x2-y2);
则W+C=x1+y1+x2-y2。
因为明显y1=y2,所以W+C=x1+x2;
x1为M中所有权值为正的点的权值,x2为N中权值为正的点的权值。
所以x1+x2=所有权值为正的点的权值之和(记为tot).
所以我们得到W+C= tot.整理一下 W = tot-C.
到这里我们就得到了闭合图的权值与简单割的容量的关系。
因为tot为定值,所以我们欲使W最大,即C最小,即此时这个简单割为最小割,此时闭合图为其源点S所在集合(除去S)。得证。
至此,我们就将最大权闭合图问题转化为了求最小割的问题。求最小割用最小割容量=最大流,即可将问题转化为求最大流的问题。
相关文章推荐
- PHP fopen()参数
- PHP fwrite()写入文件
- HDOJ1061Rightmost Digit
- Android官方技术文档翻译——ApplicationId 与 PackageName
- CodeForces 200C Football Championship(暴力枚举)
- 关闭 updatedb.mlocate?
- MyBatis延迟加载的问题
- Android上玩玩Hook?
- BZOJ 4204 取球游戏 循环矩阵优化期望递推
- PHP文件上传
- Android Studio之同一窗口打开项目
- cookie类的简单创建
- thinkphp模块
- hibernate3下载地址
- thinkphp连接数据库
- 单位冲击响应与频响以及FIR实现代码(C语言)(转)
- android解决部分手机无法通过uri获取到相册的path
- bzoj3576: [Hnoi2014]江南乐
- nodejs环境搭建(linux版)
- scrollview的无缝循环滚动