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

Posted ajmddzp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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=505;
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]+1;
    size[u]=1;
    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][2];
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][1]=size[v];
        for(int j=1;j<=n;j++)
        if(fa[j]==v)
        f[dep[u]][v][0]=max(f[dep[u]][v][0],max(f[dep[v]][j][0],f[dep[v]][j][1]));
    }
}
int ans;
int vis[maxn];
void getans(int u)
{
    int m=0;
    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][1],f[dep[u]][v][0]));
    }
    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][1]&&vis[u]==0)
        {
            ans+=m;
            vis[u]=1;
            continue;
        }
        else
        {
            getans(v);
        }
    }
}
         
         
int main()
{
    scanf("%d%d",&n,&p);
    for(int i=1;i<=p;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        addedge(x,y);
        addedge(y,x);
    }
    addedge(0,1);
    dfs(1,0);
    dp(1);
    for(int i=1;i<=n;i++)
    mp=max(mp,dep[i]);
    getans(1);
    printf("%d",n-ans);
    return 0;
}
View Code

 

以上是关于P1041 传染病控制(noip2003)(搜索)的主要内容,如果未能解决你的问题,请参考以下文章

[NOIP2003] 提高组 洛谷P1041 传染病控制

[NOIP2003] 传染病控制 搜索+剪枝

noip 2003 传染病控制(历史遗留问题2333)

[NOIP2003] 传染病控制题解

NOIP2003传染病控制

luogu cogs . [NOIP2003] 传染病控制 WA(1/2)