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 ...
随机推荐
- MYSQL join 优化 --JOIN优化实践之快速匹配
MySQL的JOIN(四):JOIN优化实践之快速匹配 优化原则:小表驱动大表,被驱动表建立索引有效,驱动表建立索引基本无效果.A left join B :A是驱动表,B是被驱动表:A right ...
- Go语言中 Print,Println 和 Printf 的区别(八)
Print 和 Println 这两个打印方式类似,只在格式上有区别 1. Println 打印的每一项之间都会有空行,Print 没有,例如: fmt.Println("go", ...
- 用Java实现对英文版《飘》的文件读取与写入操作
从文件读入<飘>的英文版,并将结果输出到文件中 要求一: 实现对英文版<飘>的字母出现次数统计 package File; import java.io.FileInputSt ...
- IDEA项目目录里下找不到src,但是src确实存在的的解决方案
写代码的时候可能出现写着写着src就找不到了,我个人认为是触发了热键导致src被隐藏了,下面就是设置src可见和不可见的操作 这个其实是被隐藏了,打开就好,位置如下:
- 封装CURD
<?php include ('ft.php'); $db=Danli::show(); //查询 //$re=$db->table('stree')->where(['name'= ...
- Storm的基本概念
Storm的基本概念 Topology:拓扑,也俗称一个任务,类似于MapReduce中的job.将Spout.Bolt整合起来的拓扑图.定义了Spout和Bolt的结合关系.并发数量.配置等等. S ...
- angular装饰器
@NgModule 元数据 NgModule 是一个带有 @NgModule() 装饰器的类.@NgModule() 装饰器是一个函数,它接受一个元数据对象,该对象的属性用来描述这个模块.其中最重要的 ...
- IDEA + SpringBoot + maven 项目文件说明
Springboot + maven + IDEA + git 项目文件介绍 1..gitignore 分布式版本控制系统git的配置文件,意思为忽略提交 在 .gitingore 文件中,遵循相应 ...
- ASP.NET Core WebAPI帮助页--Swagger简单使用1.0
1.什么是Swagger? Swagger是一个规范且完整的框架,提供描述.生产.消费和可视化RESTful API,它是为了解决Web API生成有用文档和帮助页的问题. 2.为啥选用swagg ...
- javaee 自定义标签实战
用过javaee标准标签库的里的标签应该都知道,标签的存在使得页面上的jsp脚本大大减少,甚至说没有了,大大提高了工作效率,使得页面的整洁性也有了很大的提高.下面我们就 模仿核心标签库中choose标 ...