bzoj 1143 && bzoj 2718 最长反链
来源:互联网 发布:外交官拉杆箱 知乎 编辑:程序博客网 时间:2024/05/22 16:57
题意:n个点,m条有向边,求最长反链
又到了涨姿势的时候了...(果然蒟蒻)
DAG中,有如下的一些定义和性质:
链:一条链是一些点的集合,链上任意两个点x, y,满足要么 x 能到达 y ,要么 y 能到达 x 。
反链:一条反链是一些点的集合,链上任意两个点x, y,满足 x 不能到达 y,且 y 也不能到达 x。
一个定理:最长反链长度 = 最小链覆盖(用最少的链覆盖所有顶点)
对偶定理:最长链长度 = 最小反链覆盖
那么我们要求出的就是这个有向无环图的最小链覆盖了。
最小链覆盖即路径可以相交的最小路径覆盖。
先看路径不能相交的最小路径覆盖怎么来做:
建立一个二分图,两边都是n个点,原图的每个点 i 对应两个,在左边的编号 i, 在右边的编号 n+i。
原图中如果存在一条边 (x, y),那么就在二分图中连一条 (x1, y2) 的边。
则 原图的最小路径覆盖(路径不能相交)= n-二分图最大匹配
那么路径可以相交的最小路径覆盖(最小链覆盖)呢?
将原图做一次Floyd传递闭包,得出x是否能到达y
如果两个点 x, y,满足 x 可以到达 y ,那么就在二分图中建立边 (x1, y2) 。
这里与上面不同,只要 x 能到达 y ,就直接连一条边 (x, y),
然后就转化为了路径不能相交的最小路径覆盖了。
即 原图的最小链覆盖 = n -二分图最大匹配
bzoj 1143
var n,m,x,y,ans,l :longint; i,j :longint; map :array[0..110,0..110] of boolean; link,last :array[0..210] of longint; flag :array[0..210] of boolean; pre,other :array[0..10010] of longint;procedure floyd;var i,j,k:longint;begin for k:=1 to n do for i:=1 to n do for j:=1 to n do map[i,j]:=(map[i,k] and map[k,j]) or map[i,j];end;procedure connect(x,y:longint);begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y;end;function find(x:longint):boolean;var p,q:longint;begin q:=last[x]; while (q<>0) do begin p:=other[q]; if not flag[p] then begin flag[p]:=true; if (link[p]=0) or (find(link[p])) then begin link[p]:=x; exit(true); end; end; q:=pre[q]; end; exit(false);end;begin read(n,m); for i:=1 to m do begin read(x,y); map[x,y]:=true; end; floyd; for i:=1 to n do for j:=1 to n do if map[i,j] then connect(i,n+j); ans:=0; for i:=1 to n do begin fillchar(flag,sizeof(flag),false); if find(i) then inc(ans); end; ans:=n-ans; writeln(ans);end.
bzoj 2718
var n,m,x,y,ans,l :longint; i,j :longint; map :array[0..210,0..210] of boolean; pre,other :array[0..40010] of longint; flag :array[0..410] of boolean; last,link :array[0..410] of longint;procedure connect(x,y:longint);begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y;end;procedure floyd;var i,j,k:longint;begin for k:=1 to n do for i:=1 to n do for j:=1 to n do map[i,j]:=map[i,j] or (map[i,k] and map[k,j]);end;function find(x:Longint):boolean;var p,q:longint;begin q:=last[x]; while (q<>0) do begin p:=other[q]; if not flag[p] then begin flag[p]:=true; if (link[p]=0) or find(link[p]) then begin link[p]:=x; exit(true); end; end; q:=pre[q]; end; exit(false);end;begin read(n,m); for i:=1 to m do begin read(x,y); map[x,y]:=true; end; floyd; for i:=1 to n do for j:=1 to n do if map[i,j] then connect(i,n+j); // ans:=0; for i:=1 to n do begin fillchar(flag,sizeof(flag),false); if find(i) then inc(ans); end; writeln(n-ans);end.——by Eirlys
0 0
- bzoj 1143 && bzoj 2718 最长反链
- BZOJ 1143 祭祀river 最长反链
- 最长反链(bzoj 1143: [CTSC2008]祭祀river)
- BZOJ-1143&&BZOJ-2718 祭祀river&&毕业旅行 最长反链(Floyed传递闭包+二分图匹配)
- bzoj 1143: [CTSC2008]祭祀river 求最长反链:网络流
- BZOJ 反素数ant
- bzoj 1053 反素数
- 反素数ant BZOJ
- BZOJ-1053-反素数ant
- bzoj[HAOI2007]反素数ant
- BZOJ 1053反素数ant
- bzoj 1053 反素数 HAOI2007
- BZOJ 1143 祭祀river【二分图之偏序集的最大反链】
- bzoj 最长公共子序列
- [BZOJ 1295][SCOI2009]最长距离
- 【BZOJ 1295】 [SCOI2009]最长距离
- 【bzoj 1295】[SCOI2009]最长距离
- 最长递增序列 bzoj 1049
- 数据结构学习笔记 Day 7
- Codeforces 777E 贪心或LIS+线段树
- 设计模式——简单工厂、工厂方法、抽象工厂
- FLV学习(七)FlvParser源码阅读(5)解析视频标签
- 使用shaderMaterial实现平行光下的高光效果
- bzoj 1143 && bzoj 2718 最长反链
- 算法训练 Torry的困惑(基本型)
- 计算机程序的思维逻辑 (67)
- git stash命令的使用
- CentOS安装新版git——超简单
- JAVA
- 最小生成树--九度1154[Kruskal]
- Linux中常见操作1--查看与关闭进程
- 算法训练 Anagrams问题