• AC日记——传染病控制 洛谷 P1041


    传染病控制

    思路:

      题目想问的是:

        有一棵树;

        对于除1外每个深度可以剪掉一棵子树;

        问最后剩下多少节点;

      题目意思一简单,这个题立马就变水了;

      搜索就能ac;

      数据有为链的情况,按深度为层次搜索的话要记得提前记录答案并return;

    来,上代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 305
    #define maxm 90005
    #define INF 0x7fffffff
    
    int n,m,head[maxn],E[maxm],V[maxm],cnt,ans=INF,dep[maxn];
    int l[maxn],r[maxn],size[maxn],map[maxn][maxn],deepest;
    
    bool if_[maxn];
    
    inline void in(int &now)
    {
        char Cget=getchar();now=0;
        while(Cget>'9'||Cget<'0') Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    
    inline void edge_add(int u,int v)
    {
        E[++cnt]=head[u],V[cnt]=v,head[u]=cnt;
        E[++cnt]=head[v],V[cnt]=u,head[v]=cnt;
    }
    
    void pre(int now,int fa,int deep)
    {
        deepest=max(deep,deepest),dep[now]=deep;
        map[deep][++size[deep]]=now,l[now]=++cnt;
        for(int i=head[now];i;i=E[i])
        {
            if(V[i]==fa) continue;
            pre(V[i],now,deep+1);
        }
        r[now]=cnt;
    }
    
    void dfs(int now,int ans_)
    {
        if(ans_>=ans) return ;
        if(now==deepest)
        {
            ans=ans_;
            return ;
        }
        int pos=-1;
        for(int i=1;i<=size[now+1];i++) if(!if_[l[map[now+1][i]]]) pos++;
        if(pos==-1)
        {
            ans=min(ans,ans_);
            return ;
        }
        for(int v=1;v<=size[now];v++)
        {
            if(if_[l[map[now][v]]]) continue;
            for(int i=head[map[now][v]];i;i=E[i])
            {
                if(dep[V[i]]>dep[now]&&!if_[l[V[i]]])
                {
                    for(int j=l[V[i]];j<=r[V[i]];j++) if_[j]=true;
                    dfs(now+1,ans_+pos);
                    for(int j=l[V[i]];j<=r[V[i]];j++) if_[j]=false;
                }
            }
        }
    }
    
    int main()
    {
        in(n),in(m);int u,v;
        while(m--)
        {
            in(u),in(v);
            edge_add(u,v);
        }
        cnt=0,pre(1,0,1),dfs(1,1);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    (一) kinect概述
    (五)摇杆/按钮/触摸板
    (四)Trigger
    (三)快速添加touch事件
    (二)简单触控
    Java程序设计当堂测试 9.20
    Java程序设计当堂测试感受
    暑假生活第八周总结
    暑假生活第七周总结
    暑假生活第六周总结
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6757892.html
Copyright © 2020-2023  润新知