4.26 省选模拟赛 T3 状压dp 差分求答案
LINK:T3


比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到。
一看到题求删除点的最少个 可以使得不连通。
瞬间想到最小割 发现对于10分直接跑最小割即可。
不过想要通过n^2需要一些奇技 如从Si跑到Tj 想要得到i到j+1的答案 只需要再从Tj跑到Tj+1即可。
可以发现这样做是有正确性的保证的 这样最多跑n次整张图的最大流。
且增广路不断减小 速度比较快。
const int MAXN = 40010;
int n, k, id, cc, len;
ll ans;
char a[MAXN][10][10];
int w[MAXN][10][2], S[MAXN], T[MAXN];
int lin[MAXN * 10], ver[MAXN * 100], nex[MAXN * 100], e[MAXN * 100], e1[MAXN * 100];
int vis[MAXN * 10], d[MAXN * 10], q[MAXN * 10];
inline void add(int x, int y, int z) {
ver[++len] = y;
nex[len] = lin[x];
lin[x] = len;
e[len] = z;
e1[len] = z;
ver[++len] = x;
nex[len] = lin[y];
lin[y] = len;
e[len] = 0;
e1[len] = 0;
}
inline int bfs(int S, int T) {
++cc;
int h = 0, t = 0;
q[++t] = S;
d[S] = 1;
vis[S] = cc;
while (h++ < t) {
int x = q[h];
for (int i = lin[x]; i; i = nex[i]) {
int tn = ver[i];
if (vis[tn] == cc || !e[i])
continue;
vis[tn] = cc;
q[++t] = tn;
d[tn] = d[x] + 1;
if (tn == T)
return 1;
}
}
return 0;
}
inline int dinic(int x, int flow, int T) {
if (x == T)
return flow;
int rest = flow, k;
for (int i = lin[x]; i && rest; i = nex[i]) {
int tn = ver[i];
if (e[i] && d[tn] == d[x] + 1) {
k = dinic(tn, min(rest, e[i]), T);
if (!k)
d[tn] = 0;
e[i] -= k;
e[i ^ 1] += k;
rest -= k;
}
}
return flow - rest;
}
inline void bf() {
ans = 0;
rep(1, n, i) rep(i + 1, n, j) {
rep(2, len, w) e[w] = e1[w];
int flow = 0;
while (bfs(S[i], T[j]))
while ((flow = dinic(S[i], INF, T[j]))) ans += flow;
}
putl(ans);
}
inline void sol() {
ans = 0;
rep(1, n, i) {
rep(2, len, w) e[w] = e1[w];
rep(i + 1, n, j) {
int flow = 0, cnt = 0;
while (bfs(j - 1 == i ? S[i] : T[j - 1], T[j]))
while ((flow = dinic((j - 1 == i) ? S[i] : T[j - 1], INF, T[j]))) cnt += flow;
ans += cnt;
}
}
putl(ans);
}
int main() {
freopen("T3.in", "r", stdin);
freopen("T3.out", "w", stdout);
gt(n);
gt(k);
rep(1, n, i) {
rep(1, k, j) {
if (i != n) {
gc(a[i][j]);
// rep(1,k,cc)cout<<a[i][j][cc];
// cout<<endl;
}
w[i][j][0] = ++id;
w[i][j][1] = ++id;
}
S[i] = ++id;
T[i] = ++id;
}
len = 1;
rep(1, n, i) {
rep(1, k, r) {
add(w[i][r][1], T[i], INF);
add(S[i], w[i][r][0], INF);
add(w[i][r][0], w[i][r][1], 1);
if (i != n)
rep(1, k, cc) if (a[i][r][cc] == '1') add(w[i][r][1], w[i + 1][cc][0], INF);
}
}
if (n <= 100)
bf();
else
sol();
return 0;
}
剩下的时间又又又去刚T2了就没细想。
正解:容易发现答案<=k 也同时存在 f(i,j)>=f(i,j+1)
由于点数较少 容易想到一个状压 设f[i][j][k]表示当前到了第i层此时删掉了j个点当前能到的集合为k.
一旦到达某一层集合为空 就说明删掉的这些点就可以阻断。
需要求出来 答案 利用这个状态进行差分就能快速求出到某一层的答案。
值得一提的是由于起点不固定终点基本上固定 所以倒着跑到每一个起点这样之前的dp数组还是可以使用的。
考虑转移 先承接上一层的转移 再考虑对当前集合删掉一些点。
枚举这个决策的时候直观的可以直接枚举子集 不过这样复杂度\(3^k\).
优化就是 可以利用之前的状态 只需要枚举删掉哪个点就可以得到之前的状态。
细节挺多。
const int MAXN=40010;
int n,k,maxx;ll ans;
int f[2][10][1<<9];
char a[MAXN][10][10];
int go[MAXN][1<<9];
int w[MAXN],p[1<<9];
int main()
{
freopen("T3.in","r",stdin);
freopen("T3.out","w",stdout);
//freopen("1.in","r",stdin);
gt(n);gt(k);
maxx=(1<<k)-1;
rep(1,k,i)p[1<<(i-1)]=i;
rep(1,n-1,i)
{
rep(1,k,j)
{
gc(a[i][j]);w[j]=0;
rep(1,k,c)if(a[i][j][c]=='1')w[j]=w[j]|(1<<(c-1));
}
rep(0,maxx,j)go[i][j]=go[i][j-(j&(-j))]|w[p[j&(-j)]];
}
//f[i][j][k]表示到达第i层删掉的点数为j此时当前这层状态为k所能到达的最早的层数.
memset(f,0x3f,sizeof(f));
int u=0;
fep(n,1,i)
{
u=u^1;
rep(0,k,j)rep(0,maxx,c)f[u][j][c]=f[u^1][j][go[i][c]];
f[u][0][0]=i;
rep(1,k,j)rep(0,maxx,c)
{
for(int cc=c;cc;cc=cc-(cc&(-cc)))
f[u][j][c]=min(f[u][j][c],f[u][j-1][c-(cc&(-cc))]);
}
rep(1,k,j)
{
if(f[u][j][maxx]>=INF)continue;
ans+=((f[u][j-1][maxx]>=INF?n+1:f[u][j-1][maxx])-(j==k?i+1:f[u][j][maxx]))*j;
}
}
putl(ans);
return 0;
}
4.26 省选模拟赛 T3 状压dp 差分求答案的更多相关文章
- NOIp模拟赛 巨神兵(状压DP 容斥)
\(Description\) 给定\(n\)个点\(m\)条边的有向图,求有多少个边集的子集,构成的图没有环. \(n\leq17\). \(Solution\) 问题也等价于,用不同的边集构造DA ...
- BZOJ_2734_[HNOI2012]集合选数_构造+状压DP
BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 2018.10.17 NOIP模拟 管道(状压dp)
传送门 状压dp好题. 怎么今天道道题都有点东西啊 对于今天题目神仙出题人先膜为上策:%%%%DzYoAk_UoI%%%% 设f[i][j]f[i][j]f[i][j]表示选取点的状态集合为iii,当 ...
- 模拟赛毒瘤状压DP题:Kronican
Kronican 内存限制:32 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: cqbzgm 题目描述 Mislav有N个无限体积的杯子,每一个杯子中都 ...
- 2018.09.08 NOIP模拟 division(状压dp)
这么sb的题考场居然写挂了2233. 假设n=∏iaiki" role="presentation" style="position: relative;&qu ...
- 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)
[描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...
- Codeforces 79D - Password(状压 dp+差分转化)
Codeforces 题目传送门 & 洛谷题目传送门 一个远古场的 *2800,在现在看来大概 *2600 左右罢( 不过我写这篇题解的原因大概是因为这题教会了我一个套路罢( 首先注意到每次翻 ...
- 7.12 NOI模拟赛 生成树 装压dp vector装压
LINK:生成树 这场比赛我打的真失败 T3是比较容易的 却一直刚 那道"数论" 10分其实搜一下全排列. 30分容易想到对边进行装压dp. 不过存在一些细节 可以对于一个连通块的 ...
随机推荐
- css可以修改超链接颜色吗?
超链接a标签大家都应该很熟悉,这篇文章主要的讲的是a标签的基础css样式设置,下面我们来看一下css修改超链接颜色的方法. css可以使用下面几个伪类来设置超链接: a:link :是未被访问的样式, ...
- PreparedStatement 防止sql注入 练习
使用的数据库 MariaDB 10.5.4版本 端口1054 数据库为jt_db,表 为user 数据库的建表和插入相关数据代码: create table user( id int pr ...
- 师兄大厂面试遇到这条 SQL 数据分析题,差点含泪而归!
写在前面:我是「云祁」,一枚热爱技术.会写诗的大数据开发猿.昵称来源于王安石诗中一句 [ 云之祁祁,或雨于渊 ] ,甚是喜欢. 写博客一方面是对自己学习的一点点总结及记录,另一方面则是希望能够帮助更多 ...
- day27 面向对象
day27 面向对象 目录 day27 面向对象 一.面相对象介绍 1 什么是对象 2 类于对象 二.实现面向对象编程 1 先定义类 2 属性访问 2.1 调用dict方法 2.2 类.属性 3 调用 ...
- 可见格式化模型BFC与应用
什么是BFC BFC指的是块级格式化上下文,简单的来说,BFC就是创建一个div盒子或者给已存在的盒子激活BFC,盒子内部的元素布局不影响盒子外部的元素.也就是所谓的相互隔绝,互不影响. BFC是一个 ...
- Prometheus + Grafana 监控系统搭
本文主要介绍基于Prometheus + Grafana 监控Linux服务器. 一.Prometheus 概述(略) 与其他监控系统对比 1 Prometheus vs. Zabbix Zabbix ...
- java 面向对象(二十三):关键字:abstract以及模板方法的设计模式
abstract abstract: 抽象的1.可以用来修饰:类.方法2.具体的:abstract修饰类:抽象类 * > 此类不能实例化 * > 抽象类中一定有构造器,便于子类实例化时调用 ...
- CSS3 文字边框 -webkit-text-stroke 镂空的字体
CSS边框的一个不足就是只有矩形的元素才能使用. -webkit-text-stroke可以为文字添加边框.它不但可以设置文字边框的宽度,也能设置其颜色. 而且,配合使用color: transpar ...
- vue : 无法加载文件 C:\Users\ui61895076\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
说白了就是这个编辑器不能用罢了 执行以下代码 1.鼠标右击以管理员身份运行vscode; 2. 执行:get-ExecutionPolicy,显示Restricted,表示状态是禁止的; 3. 执行: ...
- mysqldump导出表结构及数据
问题描述:有需要mysql某几张表的需求,某个数据库某几张表,导出先检查相应的数据库和表是否存在 数据泵用法:默认导出的是表结构以及表中的数据 mysqldump -uroot -p -S /data ...