P1041 传染病控制(noip2003)(搜索)

呃呃呃。。。真的是惨烈啊。。。
今天的模拟赛是真的惨。。。。。
本题,正解居然是搜索!!!!!!
蒟蒻自己歪歪了一个貌似是正解但是却连一半都没过的错解。
先解释一下自己的dp思路把。
$f[i][u][v][0/1]$表示第i秒(等效于深度)uv之间的边断还是不断。
转移有两个:
$f[dep[u]][u][v][1]=size[v];$表示此边断,然后下面的点全对答案有贡献
然后找到v的儿子
$f[dep[u]][u][v][0]=max(f[dep[u]][u][v][0],max(f[dep[v]][u][j][0],f[dep[v]][u][j][1]));$
临收卷前发现貌似第二维可以压掉,也就是:$f[dep[v]][v][0/1]$表示v上面那个边要不要删。
然后发现随手hack....
于是,我发现答案统计的时候,会有惊人的重复计算。
于是,我歪歪了好久,怎么标记统计过了,怎么返回,怎么....
然后....发现最后好像被我打成了贪心???
我在每一层去最大值,然后标记,返回,从别的子树里找最大值,然后一直重复到底层。
于是...我抱着能A掉这题的心情,笑了起来。。。
然后我rand了好多的的数据,都没有hack掉,我更开心了。
(先放dp代码:)
#include<bits/stdc++.h>
#define g(x) for(int i=head[x];i;i=e[i].next)
#define l(x) for(int l=head[x];l;i=e[l].next)
using namespace std;
const int maxn=;
int n,p;
struct edge
{
int to,next;
}e[maxn];
int head[maxn],cnt;
void addedge(int from,int to)
{
e[++cnt]=(edge){to,head[from]};
head[from]=cnt;
}
int dep[maxn];
int size[maxn];
int fa[maxn];
void dfs(int u,int f)
{
dep[u]=dep[f]+;
size[u]=;
fa[u]=f;
g(u)
{
int v=e[i].to;
if(v==f)
continue;
dfs(v,u);
size[u]+=size[v];
}
}
int f[maxn][maxn][];
int mp;
void dp(int u)
{
g(u)
{
int v=e[i].to;
if(v==fa[u])
continue;
dp(v);
f[dep[u]][u][v][]=size[v];
for(int j=;j<=n;j++)
if(fa[j]==v)
f[dep[u]][v][]=max(f[dep[u]][v][],max(f[dep[v]][j][],f[dep[v]][j][]));
}
}
int ans;
int vis[maxn];
void getans(int u)
{
int m=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa[u])
continue;
m=max(m,max(f[dep[u]][v][],f[dep[u]][v][]));
}
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa[u])
continue;
if(m==f[dep[u]][v][]&&vis[u]==)
{
ans+=m;
vis[u]=;
continue;
}
else
{
getans(v);
}
}
} int main()
{
scanf("%d%d",&n,&p);
for(int i=;i<=p;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
addedge(,);
dfs(,);
dp();
for(int i=;i<=n;i++)
mp=max(mp,dep[i]);
getans();
printf("%d",n-ans);
return ;
}
dp错在于:它会漏状态,也就是说:
我的dp是从子树开始更新,然鹅,即使我在答案统计上避免了重复,它也从一个dp变成了一个贪心,也就是说,它貌似是等效于每次在一层之内找一个子树最大的点加上,这个贪心是错的。
从而得出:dp都是错的。
因为它总会漏状态,如果从儿子更新,同深度的状态没法记录,如果从孙子更新,它的曾孙子没法更新。总而言之就是没法更新完全,也就是有后效性。
所以,如果想得出正解,就得从最下开始更新子树,而这点dp是没法做到的,所以,能够猜到正解是什么:
暴力
怎么暴力怎么写,直接更新,不需要记录状态。
这个复杂度简直玄学。。。
如果是分叉很多,这个dfs能被卡成皮皮,但是这题的数据貌似非常水....
所以,暴力的思路就是:
记录每个深度的所有点,然后对于这些同深度的点进行更新,找出最大值,一次一次向上更新,一直到根节点。
感觉这个深搜巨tm像广搜啊....但是....好吧我错了
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int n, p;
vector<int> g[maxn], dep[maxn];
int vis[maxn];
int ans, s;
void dfs(int u, int d)
{
dep[d].push_back(u);
for (int i = ; i < g[u].size(); i++)
{
dfs(g[u][i], d + );
}
}
int work(int u, int t)
{
int ss = ;
vis[u] = t;
for (int i = ; i < g[u].size(); i++)
{
ss += work(g[u][i], t);
}
return ss;
}
void getans(int d)
{
for (int i = ; i < dep[d].size(); i++)
{
if (vis[dep[d][i]])
continue;
s += work(dep[d][i], );
ans = max(s, ans);
getans(d + );
s -= work(dep[d][i], );
}
}
int main()
{
scanf("%d%d", &n, &p);
for (int i = ; i <= p; i++)
{
int x, y;
scanf("%d%d", &x, &y);
if (x > y)
swap(x, y);
g[x].push_back(y);
}
dfs(, );
getans();
printf("%d", n - ans);
return ;
}
P1041 传染病控制(noip2003)(搜索)的更多相关文章
- Luogu P1041 传染病控制(搜索)
P1041 传染病控制 题意 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这 ...
- 【搜索】P1041 传染病控制
题目链接:P1041 传染病控制 题解: 这个题目是看别人的博客做出来的,其实挺不错的一个题目,考察的东西挺多的, 一个dfs可以处理5个东西: 1.找出父亲 2.找出深度 3.每一层的节点,存进Ve ...
- P1041 传染病控制(dfs)
P1041 传染病控制 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染 ...
- 洛谷 P1041 传染病控制
P1041 传染病控制 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染 ...
- [luogu]P1041 传染病控制[dfs]
[luogu]P1041 传染病控制 ——!x^n+y^n=z^n 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的 ...
- P1041 传染病控制——暴力遍历所有相同深度的节点
P1041 传染病控制 说实话这种暴力我还是头一次见,每次病毒都会往下传染一层: 数据范围小,我们可以直接枚举当前层保护谁就好了: 用vector 记录相同层数的节点:维护已经断了的点: 如果超出最底 ...
- P1041 传染病控制【暴搜】
P1041 传染病控制 提交 10.78k 通过 3.74k 时间限制 1.00s 内存限制 125.00MB 题目提供者CCF_NOI 难度提高+/省选- 历史分数100 提交记录 查看题解 标签 ...
- Luogu1041 NOIP2003传染病控制(搜索)
暴搜加个最优性剪枝即可.一直觉得正式比赛出这种不能一眼看出来暴搜就行了的搜索题的出题人都是毒瘤. #include<iostream> #include<cstdio> #in ...
- [NOIP2003] 提高组 洛谷P1041 传染病控制
题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带 ...
随机推荐
- python语言程序设计基础(嵩天)第四章课后习题部分答案
p121: *题4.1:猜数字游戏.在程序中预设一个0~9之间的整数,让用户通过键盘输入所猜的数,如果大于预设的数,显示“遗憾,太大了!”:小于预设的数,显示“遗憾,太小了!”,如此循环,直至猜中该数 ...
- MySQL 视图(合并多表数据)引发的严重性能问题
问题背景: 一.客户环境连续多次出现性能问题,系统登入异常,数据库CPU告警. 处理过程: 1>协助排查数据库性能问题时发现如下两个较频繁的SQL导致严重的性能问题(均使用了视图合并多表数据): ...
- QCustomPlot 基础
QCutomPlot简介 官网网址及介绍 https://www.qcustomplot.com/ QCustomPlot is a Qt C++ widget for plotting and da ...
- STM32进阶之串口环形缓冲区实现
队列的概念 在此之前,我们来回顾一下队列的基本概念: 队列 (Queue):是一种先进先出(First In First Out ,简称 FIFO)的线性表,只允许在一端插入(入队),在另一端进行删除 ...
- Vijos 1067守望者的烦恼
背景 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她传送到后面的监狱内查看,她比较懒,一般不查看 ...
- MySQL复制从库建立-xtracebackup方式
Percona XtraBackup工具提供了一种在系统运行时执行MySQL数据热备份的方法. Percona XtraBackup在事务系统上执行联机非阻塞,紧密压缩,高度安全的完整备份,因此在计划 ...
- Oracle报错注入总结
0x00 前言 在oracle注入时候出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中. 使用报错注入需要使用类似 1=[报错语句],1>[报错语句], ...
- [JZOJ5773]【NOIP2008模拟】简单数学题
Description 话说, 小X是个数学大佬,他喜欢做数学题.有一天,小X想考一考小Y.他问了小Y一道数学题.题目如下: 对于一个正整数N,存在一个正整数T(0<T&l ...
- 就改了get,却不让我set?——Java内省机制的神奇行为举止一例
[相关类库]org.apache.commons.beanutils.BeanUtils,提供对Java反射和自省API的包装,其中底层使用到了Java的内省方法.[内省的一般应用形式]通过类Intr ...
- Vulnhub靶场渗透练习(一) Breach1.0
打开靶场 固定ip需要更改虚拟机为仅主机模式 192.168.110.140 打开网页http://192.168.110.140/index.html 查看源代码发现可以加密字符串 猜测base64 ...