1143, 3997: Dilworth定理的简单应用
偏序集上的最小链覆盖等价于求最长反链
最小不交链覆盖等于传递闭包后最小链覆盖
最小链覆盖大小等于点数减去二分图最大匹配大小
二分图最小点覆盖大小等于二分图匹配大小
二分图最小点覆盖与二分图最大独立集对偶
建图完后,这个二分图最大独立集等价于最长反链。
于是两道题
1143: [CTSC2008]祭祀river
求偏序集上的最长反链
转换成偏序集上的最小链覆盖
求个闭包,转换成最小路径覆盖,二分图匹配一发
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
const int MAXN = 210;
const int MAXM = MAXN * MAXN * 2;
const int INF = 0x3f3f3f3f;
int head[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot = 1;
inline void addedge(int b, int e, int v) {
nxt[++tot] = head[b]; to[head[b] = tot] = e; val[tot] = v;
nxt[++tot] = head[e]; to[head[e] = tot] = b; val[tot] = 0;
}
std::queue<int> q;
int S, T, dis[MAXN];
bool bfs() {
for (int i = S; i <= T; ++i) dis[i] = 0;
dis[S] = 1; q.push(S);
while (!q.empty()) {
int t = q.front(); q.pop();
for (int i = head[t]; i; i = nxt[i])
if (val[i] && !dis[to[i]]) {
dis[to[i]] = dis[t] + 1;
q.push(to[i]);
}
}
return dis[T] > 0;
}
int dinic(int u, int minv) {
if (u == T || !minv) return minv;
int t, res = 0;
for (int i = head[u]; i; i = nxt[i])
if (val[i] && dis[to[i]] == dis[u] + 1 && (t = dinic(to[i], std::min(minv, val[i])))) {
val[i] -= t;
val[i ^ 1] += t;
res += t;
minv -= t;
if (!minv) break;
}
if (!res) dis[u] = -1;
return res;
}
int n, m, t1, t2, f[MAXN][MAXN];
int main() {
scanf("%d%d", &n, &m);
S = 0, T = n << 1 | 1;
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &t1, &t2);
f[t1][t2] = true;
}
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
f[i][j] |= f[i][k] & f[k][j];
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (f[i][j])
addedge(i, j + n, 1);
for (int i = 1; i <= n; ++i) {
addedge(S, i, 1);
addedge(i + n, T, 1);
}
int ans = n;
while (bfs()) ans -= dinic(S, INF);
printf("%d\n", ans);
return 0;
}
3997: [TJOI2015]组合数学
给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走。问至少走多少次才能将财宝捡完。此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走多少次才能把财宝全部捡完。
求偏序集上的最小链覆盖,转换为最长反链覆盖
于是只要DP出反链就好了,前(其实是后)缀和优化一下
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int MAXN = 1010;
int f[MAXN][MAXN], suc[MAXN][MAXN], map[MAXN][MAXN], n, m;
inline void getmax(int & x, const int y) { if (x < y) x = y; }
int main() {
int T; scanf("%d", &T);
while (T --> 0) {
scanf("%d%d", &n, &m);
for (int i = 0; i <= n + 1; ++i)
for (int j = 0; j <= m + 1; ++j)
f[i][j] = suc[i][j] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) scanf("%d", map[i] + j);
for (int j = m; j; --j) {
getmax(f[i][j], suc[i - 1][j + 1] + map[i][j]);
suc[i][j] = std::max(suc[i][j + 1], suc[i - 1][j]);
getmax(suc[i][j], f[i][j]);
}
}
printf("%d\n", suc[n][1]);
}
return 0;
}
1143, 3997: Dilworth定理的简单应用的更多相关文章
- bzoj 3997 Dilworth定理
看到这道题感觉像是网络流,如果没有权值,可以用DAG最小路径覆盖,有权值,感觉可以求一个上下界最小可行流,但内存卡了....时间估计也悬. 正解要用到一些数学知识,这里梳理一下: 定义: 偏序关系: ...
- BZOJ.1143.[CTSC2008]祭祀(Dilworth定理 最大流ISAP)
题目链接 题目是求最长反链,反链指点集内任意两点不能互相到达. 根据Dilworth定理,在DAG中,\[最长反链 = 最小路径覆盖 = V - 最大匹配数\] 用Floyd求一遍传递闭包后,在所有可 ...
- 【codevs1044】导弹拦截问题与Dilworth定理
题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...
- (转载)偏序集的Dilworth定理学习
导弹拦截是一个经典问题:求一个序列的最长不上升子序列,以及求能最少划分成几组不上升子序列.第一问是经典动态规划,第二问直接的方法是最小路径覆盖, 但是二分图匹配的复杂度较高,我们可以将其转化成求最长上 ...
- codevs1044:dilworth定理
http://www.cnblogs.com/submarine/archive/2011/08/03/2126423.html dilworth定理的介绍 题目大意:求一个序列的lds 同时找出这个 ...
- 如何使用Dilworth定理
相关例题:NOIP 1999导弹拦截 遇到这题不会去网上搜Dilworth定理,太难受了,看不懂证明 但是,我知道怎么使用了,管那么多,会用就完事了 学习自这篇文章 -1.为什么我不想学证明这个定理 ...
- 洛谷P1020 导弹拦截 题解 LIS扩展题 Dilworth定理
题目链接:https://www.luogu.com.cn/problem/P1020 题目大意: 给你一串数,求: 这串数的最长不上升子序列的长度: 最少划分成多少个子序列是的这些子序列都是不上升子 ...
- 偏序集的Dilworth定理
定理1 令(X,≤)是一个有限偏序集,并令r是其最大链的大小.则X可以被划分成r个但不能再少的反链.其对偶定理称为Dilworth定理:定理2 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小. ...
- hdu1051(LIS | Dilworth定理)
这题根据的Dilworth定理,链的最小个数=反链的最大长度 , 然后就是排序LIS了 链-反链-Dilworth定理 hdu1051 #include <iostream> #inclu ...
随机推荐
- AcWing175电路维修
这是一道在luogu的蓝题,在yxc大佬的讲解下AC掉了(百般调试) 首先这道题给了一个字符串矩阵,/ \表示相连哪两个节点,只可以走/ \所连接的两个点,但我们可以旋转每一个边,询问从1,1 走到 ...
- 小白学习django第五站-简易案例
首先在setting.py文件中编写数据库配置内容 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': ' ...
- JAVA文件类工具
FileUtil package cn.jiangzeyin.util.file; import org.springframework.util.Assert; import java.io.*; ...
- PermissionError: [Errno 13] Permission denied: '/run/user/0/jupyter'
解决办法:需要给/run/user整个目录开放权限,不能单独给'/run/user/0/jupyter'这个文件,因为jupyter是需要往目录中添加文件,/run/user/0/jupyter,此时 ...
- 进程之multiprocessing模块代码篇
这里再把之前的内容总结和补充一下: 并发和并行: 你在干坏事,来了一个电话,干完坏事再去接电话,说明你既不是并发也不是并行. 你在干坏事,来了一个电话,你接完电话接着干坏事,说明你支持并发 你在干坏事 ...
- leetcode难题
4 寻找两个有序数组的中位数 35.9% 困难 10 正则表达式匹配 24.6% 困难 23 合并K个排序链表 47.4% 困难 25 K ...
- CSDN添加文章目录
在发表的文章中,系统根据文章中H1到H6标签自动生成文章目录. 一.发表文章的时候合理使用“标题”标签. 二.目录生成.只要在文章中使用了“标题1”这样的功能,就可以在博文开头看到文章的目录.
- 关于swiper 4的coverflowEffect(3d)
轮播效果: HTML: <div class="swiper-container successful_swiper"> <div class="swi ...
- iscsi原理
iscsi原理 一,[名词解释] SCSI:小型计算机系统接口,SCSI作为i输入/输出接口, FC:光纤通道 DAS:直连式存储,指将存储设备通过SCSI接口或光纤通道直接连到一台计算机上. NAS ...
- FTP部署与使用
1.1 环境检查 [root@www ~]# cat /etc/redhat-release #系统版本,6系列等区别不大,都可以 CentOS Linux release 7.5.1804 (Cor ...